Remove unused marshalling for SAMR_SET_SEC_OBJ.
[vlendec/samba-autobuild/.git] / source3 / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4    Copyright (C) Tim Potter                        2000-2001,
5    Copyright (C) Andrew Tridgell              1992-1997,2000,
6    Copyright (C) Rafal Szczesniak                       2002.
7    Copyright (C) Jeremy Allison                         2005.
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24
25 /* Connect to SAMR database */
26
27 NTSTATUS rpccli_samr_connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
28                              uint32 access_mask, POLICY_HND *connect_pol)
29 {
30         prs_struct qbuf, rbuf;
31         SAMR_Q_CONNECT q;
32         SAMR_R_CONNECT r;
33         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
34
35         DEBUG(10,("cli_samr_connect to %s\n", cli->cli->desthost));
36
37         ZERO_STRUCT(q);
38         ZERO_STRUCT(r);
39
40         /* Marshall data and send request */
41
42         init_samr_q_connect(&q, cli->cli->desthost, access_mask);
43
44         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CONNECT,
45                 q, r,
46                 qbuf, rbuf,
47                 samr_io_q_connect,
48                 samr_io_r_connect,
49                 NT_STATUS_UNSUCCESSFUL); 
50         /* Return output parameters */
51
52         if (NT_STATUS_IS_OK(result = r.status)) {
53                 *connect_pol = r.connect_pol;
54 #ifdef __INSURE__
55                 connect_pol->marker = malloc(1);
56 #endif
57         }
58
59         return result;
60 }
61
62 /* Connect to SAMR database */
63
64 NTSTATUS rpccli_samr_connect4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
65                            uint32 access_mask, POLICY_HND *connect_pol)
66 {
67         prs_struct qbuf, rbuf;
68         SAMR_Q_CONNECT4 q;
69         SAMR_R_CONNECT4 r;
70         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
71
72         ZERO_STRUCT(q);
73         ZERO_STRUCT(r);
74
75         /* Marshall data and send request */
76
77         init_samr_q_connect4(&q, cli->cli->desthost, access_mask);
78
79         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CONNECT4,
80                 q, r,
81                 qbuf, rbuf,
82                 samr_io_q_connect4,
83                 samr_io_r_connect4,
84                 NT_STATUS_UNSUCCESSFUL); 
85
86         /* Return output parameters */
87
88         if (NT_STATUS_IS_OK(result = r.status)) {
89                 *connect_pol = r.connect_pol;
90 #ifdef __INSURE__
91                 connect_pol->marker = malloc(1);
92 #endif
93         }
94
95         return result;
96 }
97
98 /* Add a domain group member */
99
100 NTSTATUS rpccli_samr_add_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
101                                POLICY_HND *group_pol, uint32 rid)
102 {
103         prs_struct qbuf, rbuf;
104         SAMR_Q_ADD_GROUPMEM q;
105         SAMR_R_ADD_GROUPMEM r;
106         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
107
108         DEBUG(10,("cli_samr_add_groupmem\n"));
109
110         ZERO_STRUCT(q);
111         ZERO_STRUCT(r);
112
113         /* Marshall data and send request */
114
115         init_samr_q_add_groupmem(&q, group_pol, rid);
116
117         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ADD_GROUPMEM,
118                 q, r,
119                 qbuf, rbuf,
120                 samr_io_q_add_groupmem,
121                 samr_io_r_add_groupmem,
122                 NT_STATUS_UNSUCCESSFUL); 
123
124         /* Return output parameters */
125
126         result = r.status;
127
128         return result;
129 }
130
131 /* Delete a domain group member */
132
133 NTSTATUS rpccli_samr_del_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
134                                POLICY_HND *group_pol, uint32 rid)
135 {
136         prs_struct qbuf, rbuf;
137         SAMR_Q_DEL_GROUPMEM q;
138         SAMR_R_DEL_GROUPMEM r;
139         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
140
141         DEBUG(10,("cli_samr_del_groupmem\n"));
142
143         ZERO_STRUCT(q);
144         ZERO_STRUCT(r);
145
146         /* Marshall data and send request */
147
148         init_samr_q_del_groupmem(&q, group_pol, rid);
149
150         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DEL_GROUPMEM,
151                 q, r,
152                 qbuf, rbuf,
153                 samr_io_q_del_groupmem,
154                 samr_io_r_del_groupmem,
155                 NT_STATUS_UNSUCCESSFUL); 
156
157         /* Return output parameters */
158
159         result = r.status;
160
161         return result;
162 }
163
164 /* Query user info */
165
166 NTSTATUS rpccli_samr_query_userinfo(struct rpc_pipe_client *cli,
167                                     TALLOC_CTX *mem_ctx,
168                                     const POLICY_HND *user_pol,
169                                     uint16 switch_value, 
170                                     SAM_USERINFO_CTR **ctr)
171 {
172         prs_struct qbuf, rbuf;
173         SAMR_Q_QUERY_USERINFO q;
174         SAMR_R_QUERY_USERINFO r;
175         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
176
177         DEBUG(10,("cli_samr_query_userinfo\n"));
178
179         ZERO_STRUCT(q);
180         ZERO_STRUCT(r);
181
182         /* Marshall data and send request */
183
184         init_samr_q_query_userinfo(&q, user_pol, switch_value);
185
186         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERINFO,
187                 q, r,
188                 qbuf, rbuf,
189                 samr_io_q_query_userinfo,
190                 samr_io_r_query_userinfo,
191                 NT_STATUS_UNSUCCESSFUL); 
192
193         /* Return output parameters */
194
195         result = r.status;
196         *ctr = r.ctr;
197
198         return result;
199 }
200
201 /* Set group info */
202
203 NTSTATUS rpccli_samr_set_groupinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
204                                 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
205 {
206         prs_struct qbuf, rbuf;
207         SAMR_Q_SET_GROUPINFO q;
208         SAMR_R_SET_GROUPINFO r;
209         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
210
211         DEBUG(10,("cli_samr_set_groupinfo\n"));
212
213         ZERO_STRUCT(q);
214         ZERO_STRUCT(r);
215
216         /* Marshall data and send request */
217
218         init_samr_q_set_groupinfo(&q, group_pol, ctr);
219
220         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_GROUPINFO,
221                 q, r,
222                 qbuf, rbuf,
223                 samr_io_q_set_groupinfo,
224                 samr_io_r_set_groupinfo,
225                 NT_STATUS_UNSUCCESSFUL); 
226
227         /* Return output parameters */
228
229         result = r.status;
230
231         return result;
232 }
233
234 /* Query group info */
235
236 NTSTATUS rpccli_samr_query_groupinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
237                                   POLICY_HND *group_pol, uint32 info_level, 
238                                   GROUP_INFO_CTR **ctr)
239 {
240         prs_struct qbuf, rbuf;
241         SAMR_Q_QUERY_GROUPINFO q;
242         SAMR_R_QUERY_GROUPINFO r;
243         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
244
245         DEBUG(10,("cli_samr_query_groupinfo\n"));
246
247         ZERO_STRUCT(q);
248         ZERO_STRUCT(r);
249
250         /* Marshall data and send request */
251
252         init_samr_q_query_groupinfo(&q, group_pol, info_level);
253
254         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_GROUPINFO,
255                 q, r,
256                 qbuf, rbuf,
257                 samr_io_q_query_groupinfo,
258                 samr_io_r_query_groupinfo,
259                 NT_STATUS_UNSUCCESSFUL); 
260
261         *ctr = r.ctr;
262
263         /* Return output parameters */
264
265         result = r.status;
266
267         return result;
268 }
269
270 /* Query user groups */
271
272 NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
273                                       TALLOC_CTX *mem_ctx, 
274                                       POLICY_HND *user_pol,
275                                       uint32 *num_groups, 
276                                       DOM_GID **gid)
277 {
278         prs_struct qbuf, rbuf;
279         SAMR_Q_QUERY_USERGROUPS q;
280         SAMR_R_QUERY_USERGROUPS r;
281         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
282
283         DEBUG(10,("cli_samr_query_usergroups\n"));
284
285         ZERO_STRUCT(q);
286         ZERO_STRUCT(r);
287
288         /* Marshall data and send request */
289
290         init_samr_q_query_usergroups(&q, user_pol);
291
292         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERGROUPS,
293                 q, r,
294                 qbuf, rbuf,
295                 samr_io_q_query_usergroups,
296                 samr_io_r_query_usergroups,
297                 NT_STATUS_UNSUCCESSFUL); 
298
299         /* Return output parameters */
300
301         if (NT_STATUS_IS_OK(result = r.status)) {
302                 *num_groups = r.num_entries;
303                 *gid = r.gid;
304         }
305
306         return result;
307 }
308
309 /* Set alias info */
310
311 NTSTATUS rpccli_samr_set_aliasinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
312                                 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
313 {
314         prs_struct qbuf, rbuf;
315         SAMR_Q_SET_ALIASINFO q;
316         SAMR_R_SET_ALIASINFO r;
317         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
318
319         DEBUG(10,("cli_samr_set_aliasinfo\n"));
320
321         ZERO_STRUCT(q);
322         ZERO_STRUCT(r);
323
324         /* Marshall data and send request */
325
326         init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
327
328         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_ALIASINFO,
329                 q, r,
330                 qbuf, rbuf,
331                 samr_io_q_set_aliasinfo,
332                 samr_io_r_set_aliasinfo,
333                 NT_STATUS_UNSUCCESSFUL); 
334
335         /* Return output parameters */
336
337         result = r.status;
338
339         return result;
340 }
341
342 /* Query user aliases */
343
344 NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
345                                        TALLOC_CTX *mem_ctx, 
346                                        POLICY_HND *dom_pol, uint32 num_sids,
347                                        DOM_SID2 *sid,
348                                        uint32 *num_aliases, uint32 **als_rids)
349 {
350         prs_struct qbuf, rbuf;
351         SAMR_Q_QUERY_USERALIASES q;
352         SAMR_R_QUERY_USERALIASES r;
353         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
354         int i;
355         uint32 *sid_ptrs;
356         
357         DEBUG(10,("cli_samr_query_useraliases\n"));
358
359         ZERO_STRUCT(q);
360         ZERO_STRUCT(r);
361
362         if (num_sids) {
363                 sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
364                 if (sid_ptrs == NULL)
365                         return NT_STATUS_NO_MEMORY;
366         } else {
367                 sid_ptrs = NULL;
368         }
369         
370         for (i=0; i<num_sids; i++)
371                 sid_ptrs[i] = 1;
372
373         /* Marshall data and send request */
374
375         init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
376
377         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERALIASES,
378                 q, r,
379                 qbuf, rbuf,
380                 samr_io_q_query_useraliases,
381                 samr_io_r_query_useraliases,
382                 NT_STATUS_UNSUCCESSFUL); 
383
384         /* Return output parameters */
385
386         if (NT_STATUS_IS_OK(result = r.status)) {
387                 *num_aliases = r.num_entries;
388                 *als_rids = r.rid;
389         }
390
391         return result;
392 }
393
394 /* Query user groups */
395
396 NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
397                                     TALLOC_CTX *mem_ctx,
398                                     POLICY_HND *group_pol, uint32 *num_mem, 
399                                     uint32 **rid, uint32 **attr)
400 {
401         prs_struct qbuf, rbuf;
402         SAMR_Q_QUERY_GROUPMEM q;
403         SAMR_R_QUERY_GROUPMEM r;
404         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
405
406         DEBUG(10,("cli_samr_query_groupmem\n"));
407
408         ZERO_STRUCT(q);
409         ZERO_STRUCT(r);
410
411         /* Marshall data and send request */
412
413         init_samr_q_query_groupmem(&q, group_pol);
414
415         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_GROUPMEM,
416                 q, r,
417                 qbuf, rbuf,
418                 samr_io_q_query_groupmem,
419                 samr_io_r_query_groupmem,
420                 NT_STATUS_UNSUCCESSFUL); 
421
422         /* Return output parameters */
423
424         if (NT_STATUS_IS_OK(result = r.status)) {
425                 *num_mem = r.num_entries;
426                 *rid = r.rid;
427                 *attr = r.attr;
428         }
429
430         return result;
431 }
432
433 /**
434  * Enumerate domain users
435  *
436  * @param cli client state structure
437  * @param mem_ctx talloc context
438  * @param pol opened domain policy handle
439  * @param start_idx starting index of enumeration, returns context for
440                     next enumeration
441  * @param acb_mask account control bit mask (to enumerate some particular
442  *                 kind of accounts)
443  * @param size max acceptable size of response
444  * @param dom_users returned array of domain user names
445  * @param rids returned array of domain user RIDs
446  * @param num_dom_users numer returned entries
447  * 
448  * @return NTSTATUS returned in rpc response
449  **/
450
451 NTSTATUS rpccli_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
452                                  POLICY_HND *pol, uint32 *start_idx, uint32 acb_mask,
453                                  uint32 size, char ***dom_users, uint32 **rids,
454                                  uint32 *num_dom_users)
455 {
456         prs_struct qbuf;
457         prs_struct rbuf;
458         SAMR_Q_ENUM_DOM_USERS q;
459         SAMR_R_ENUM_DOM_USERS r;
460         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
461         int i;
462         
463         DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
464
465         ZERO_STRUCT(q);
466         ZERO_STRUCT(r);
467         
468         /* always init this */
469         *num_dom_users = 0;
470         
471         /* Fill query structure with parameters */
472
473         init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, size);
474         
475         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_USERS,
476                 q, r,
477                 qbuf, rbuf,
478                 samr_io_q_enum_dom_users,
479                 samr_io_r_enum_dom_users,
480                 NT_STATUS_UNSUCCESSFUL); 
481
482         result = r.status;
483
484         if (!NT_STATUS_IS_OK(result) &&
485             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
486                 goto done;
487         
488         *start_idx = r.next_idx;
489         *num_dom_users = r.num_entries2;
490
491         if (r.num_entries2) {
492                 /* allocate memory needed to return received data */    
493                 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
494                 if (!*rids) {
495                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
496                         return NT_STATUS_NO_MEMORY;
497                 }
498                 
499                 *dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
500                 if (!*dom_users) {
501                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
502                         return NT_STATUS_NO_MEMORY;
503                 }
504                 
505                 /* fill output buffers with rpc response */
506                 for (i = 0; i < r.num_entries2; i++) {
507                         fstring conv_buf;
508                         
509                         (*rids)[i] = r.sam[i].rid;
510                         unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf));
511                         (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
512                 }
513         }
514         
515 done:
516         return result;
517 }
518
519 /* Enumerate domain groups */
520
521 NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
522                                      TALLOC_CTX *mem_ctx, 
523                                      POLICY_HND *pol, uint32 *start_idx, 
524                                      uint32 size, struct acct_info **dom_groups,
525                                      uint32 *num_dom_groups)
526 {
527         prs_struct qbuf, rbuf;
528         SAMR_Q_ENUM_DOM_GROUPS q;
529         SAMR_R_ENUM_DOM_GROUPS r;
530         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
531         uint32 name_idx, i;
532
533         DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
534
535         ZERO_STRUCT(q);
536         ZERO_STRUCT(r);
537
538         /* Marshall data and send request */
539
540         init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
541
542         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_GROUPS,
543                 q, r,
544                 qbuf, rbuf,
545                 samr_io_q_enum_dom_groups,
546                 samr_io_r_enum_dom_groups,
547                 NT_STATUS_UNSUCCESSFUL); 
548
549         /* Return output parameters */
550
551         result = r.status;
552
553         if (!NT_STATUS_IS_OK(result) &&
554             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
555                 goto done;
556
557         *num_dom_groups = r.num_entries2;
558
559         if (*num_dom_groups == 0)
560                 goto done;
561
562         if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
563                 result = NT_STATUS_NO_MEMORY;
564                 goto done;
565         }
566
567         memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
568
569         name_idx = 0;
570
571         for (i = 0; i < *num_dom_groups; i++) {
572
573                 (*dom_groups)[i].rid = r.sam[i].rid;
574
575                 if (r.sam[i].hdr_name.buffer) {
576                         unistr2_to_ascii((*dom_groups)[i].acct_name,
577                                          &r.uni_grp_name[name_idx],
578                                          sizeof((*dom_groups)[i].acct_name));
579                         name_idx++;
580                 }
581
582                 *start_idx = r.next_idx;
583         }
584
585  done:
586         return result;
587 }
588
589 /* Enumerate domain groups */
590
591 NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
592                                      TALLOC_CTX *mem_ctx, 
593                                      POLICY_HND *pol, uint32 *start_idx, 
594                                      uint32 size, struct acct_info **dom_aliases,
595                                      uint32 *num_dom_aliases)
596 {
597         prs_struct qbuf, rbuf;
598         SAMR_Q_ENUM_DOM_ALIASES q;
599         SAMR_R_ENUM_DOM_ALIASES r;
600         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601         uint32 name_idx, i;
602
603         DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
604
605         ZERO_STRUCT(q);
606         ZERO_STRUCT(r);
607
608         /* Marshall data and send request */
609
610         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
611
612         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_ALIASES,
613                 q, r,
614                 qbuf, rbuf,
615                 samr_io_q_enum_dom_aliases,
616                 samr_io_r_enum_dom_aliases,
617                 NT_STATUS_UNSUCCESSFUL); 
618
619         /* Return output parameters */
620
621         result = r.status;
622
623         if (!NT_STATUS_IS_OK(result) &&
624             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
625                 goto done;
626         }
627
628         *num_dom_aliases = r.num_entries2;
629
630         if (*num_dom_aliases == 0)
631                 goto done;
632
633         if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
634                 result = NT_STATUS_NO_MEMORY;
635                 goto done;
636         }
637
638         memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
639
640         name_idx = 0;
641
642         for (i = 0; i < *num_dom_aliases; i++) {
643
644                 (*dom_aliases)[i].rid = r.sam[i].rid;
645
646                 if (r.sam[i].hdr_name.buffer) {
647                         unistr2_to_ascii((*dom_aliases)[i].acct_name,
648                                          &r.uni_grp_name[name_idx],
649                                          sizeof((*dom_aliases)[i].acct_name));
650                         name_idx++;
651                 }
652
653                 *start_idx = r.next_idx;
654         }
655
656  done:
657         return result;
658 }
659
660 /* Query alias members */
661
662 NTSTATUS rpccli_samr_query_aliasmem(struct rpc_pipe_client *cli,
663                                     TALLOC_CTX *mem_ctx,
664                                     POLICY_HND *alias_pol, uint32 *num_mem, 
665                                     DOM_SID **sids)
666 {
667         prs_struct qbuf, rbuf;
668         SAMR_Q_QUERY_ALIASMEM q;
669         SAMR_R_QUERY_ALIASMEM r;
670         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
671         uint32 i;
672
673         DEBUG(10,("cli_samr_query_aliasmem\n"));
674
675         ZERO_STRUCT(q);
676         ZERO_STRUCT(r);
677
678         /* Marshall data and send request */
679
680         init_samr_q_query_aliasmem(&q, alias_pol);
681
682         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_ALIASMEM,
683                 q, r,
684                 qbuf, rbuf,
685                 samr_io_q_query_aliasmem,
686                 samr_io_r_query_aliasmem,
687                 NT_STATUS_UNSUCCESSFUL); 
688
689         /* Return output parameters */
690
691         if (!NT_STATUS_IS_OK(result = r.status)) {
692                 goto done;
693         }
694
695         *num_mem = r.num_sids;
696
697         if (*num_mem == 0) {
698                 *sids = NULL;
699                 result = NT_STATUS_OK;
700                 goto done;
701         }
702
703         if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
704                 result = NT_STATUS_UNSUCCESSFUL;
705                 goto done;
706         }
707
708         for (i = 0; i < *num_mem; i++) {
709                 (*sids)[i] = r.sid[i].sid;
710         }
711
712  done:
713         return result;
714 }
715
716 /* Add an alias member */
717
718 NTSTATUS rpccli_samr_add_aliasmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
719                                POLICY_HND *alias_pol, DOM_SID *member)
720 {
721         prs_struct qbuf, rbuf;
722         SAMR_Q_ADD_ALIASMEM q;
723         SAMR_R_ADD_ALIASMEM r;
724         NTSTATUS result;
725
726         DEBUG(10,("cli_samr_add_aliasmem"));
727
728         ZERO_STRUCT(q);
729         ZERO_STRUCT(r);
730
731         /* Marshall data and send request */
732
733         init_samr_q_add_aliasmem(&q, alias_pol, member);
734
735         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ADD_ALIASMEM,
736                 q, r,
737                 qbuf, rbuf,
738                 samr_io_q_add_aliasmem,
739                 samr_io_r_add_aliasmem,
740                 NT_STATUS_UNSUCCESSFUL); 
741
742         result = r.status;
743
744         return result;
745 }
746
747 /* Delete an alias member */
748
749 NTSTATUS rpccli_samr_del_aliasmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
750                                POLICY_HND *alias_pol, DOM_SID *member)
751 {
752         prs_struct qbuf, rbuf;
753         SAMR_Q_DEL_ALIASMEM q;
754         SAMR_R_DEL_ALIASMEM r;
755         NTSTATUS result;
756
757         DEBUG(10,("cli_samr_del_aliasmem"));
758
759         ZERO_STRUCT(q);
760         ZERO_STRUCT(r);
761
762         /* Marshall data and send request */
763
764         init_samr_q_del_aliasmem(&q, alias_pol, member);
765
766         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DEL_ALIASMEM,
767                 q, r,
768                 qbuf, rbuf,
769                 samr_io_q_del_aliasmem,
770                 samr_io_r_del_aliasmem,
771                 NT_STATUS_UNSUCCESSFUL); 
772
773         result = r.status;
774
775         return result;
776 }
777
778 /* Query alias info */
779
780 NTSTATUS rpccli_samr_query_alias_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
781                                    POLICY_HND *alias_pol, uint16 switch_value,
782                                    ALIAS_INFO_CTR *ctr)
783 {
784         prs_struct qbuf, rbuf;
785         SAMR_Q_QUERY_ALIASINFO q;
786         SAMR_R_QUERY_ALIASINFO r;
787         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
788
789         DEBUG(10,("cli_samr_query_alias_info\n"));
790
791         ZERO_STRUCT(q);
792         ZERO_STRUCT(r);
793
794         /* Marshall data and send request */
795
796         init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
797
798         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_ALIASINFO,
799                 q, r,
800                 qbuf, rbuf,
801                 samr_io_q_query_aliasinfo,
802                 samr_io_r_query_aliasinfo,
803                 NT_STATUS_UNSUCCESSFUL); 
804
805         /* Return output parameters */
806
807         if (!NT_STATUS_IS_OK(result = r.status)) {
808                 goto done;
809         }
810
811         *ctr = *r.ctr;
812
813   done:
814
815         return result;
816 }
817
818 /* Query domain info */
819
820 NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
821                                     TALLOC_CTX *mem_ctx, 
822                                     POLICY_HND *domain_pol,
823                                     uint16 switch_value,
824                                     SAM_UNK_CTR *ctr)
825 {
826         prs_struct qbuf, rbuf;
827         SAMR_Q_QUERY_DOMAIN_INFO q;
828         SAMR_R_QUERY_DOMAIN_INFO r;
829         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
830
831         DEBUG(10,("cli_samr_query_dom_info\n"));
832
833         ZERO_STRUCT(q);
834         ZERO_STRUCT(r);
835
836         /* Marshall data and send request */
837
838         init_samr_q_query_domain_info(&q, domain_pol, switch_value);
839
840         r.ctr = ctr;
841
842         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DOMAIN_INFO,
843                 q, r,
844                 qbuf, rbuf,
845                 samr_io_q_query_domain_info,
846                 samr_io_r_query_domain_info,
847                 NT_STATUS_UNSUCCESSFUL); 
848
849         /* Return output parameters */
850
851         if (!NT_STATUS_IS_OK(result = r.status)) {
852                 goto done;
853         }
854
855  done:
856
857         return result;
858 }
859
860 /* Query domain info2 */
861
862 NTSTATUS rpccli_samr_query_dom_info2(struct rpc_pipe_client *cli,
863                                      TALLOC_CTX *mem_ctx, 
864                                      POLICY_HND *domain_pol,
865                                      uint16 switch_value,
866                                      SAM_UNK_CTR *ctr)
867 {
868         prs_struct qbuf, rbuf;
869         SAMR_Q_QUERY_DOMAIN_INFO2 q;
870         SAMR_R_QUERY_DOMAIN_INFO2 r;
871         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
872
873         DEBUG(10,("cli_samr_query_dom_info2\n"));
874
875         ZERO_STRUCT(q);
876         ZERO_STRUCT(r);
877
878         /* Marshall data and send request */
879
880         init_samr_q_query_domain_info2(&q, domain_pol, switch_value);
881
882         r.ctr = ctr;
883
884         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DOMAIN_INFO2,
885                 q, r,
886                 qbuf, rbuf,
887                 samr_io_q_query_domain_info2,
888                 samr_io_r_query_domain_info2,
889                 NT_STATUS_UNSUCCESSFUL); 
890
891         /* Return output parameters */
892
893         if (!NT_STATUS_IS_OK(result = r.status)) {
894                 goto done;
895         }
896
897  done:
898
899         return result;
900 }
901
902 /* Set domain info */
903
904 NTSTATUS rpccli_samr_set_domain_info(struct rpc_pipe_client *cli,
905                                      TALLOC_CTX *mem_ctx, 
906                                      POLICY_HND *domain_pol,
907                                      uint16 switch_value,
908                                      SAM_UNK_CTR *ctr)
909 {
910         prs_struct qbuf, rbuf;
911         SAMR_Q_SET_DOMAIN_INFO q;
912         SAMR_R_SET_DOMAIN_INFO r;
913         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
914
915         DEBUG(10,("cli_samr_set_domain_info\n"));
916
917         ZERO_STRUCT(q);
918         ZERO_STRUCT(r);
919
920         /* Marshall data and send request */
921
922         init_samr_q_set_domain_info(&q, domain_pol, switch_value, ctr);
923
924         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_DOMAIN_INFO,
925                 q, r,
926                 qbuf, rbuf,
927                 samr_io_q_set_domain_info,
928                 samr_io_r_set_domain_info,
929                 NT_STATUS_UNSUCCESSFUL); 
930
931         /* Return output parameters */
932
933         if (!NT_STATUS_IS_OK(result = r.status)) {
934                 goto done;
935         }
936
937  done:
938
939         return result;
940 }
941
942 /* User change password */
943
944 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
945                                     TALLOC_CTX *mem_ctx, 
946                                     const char *username, 
947                                     const char *newpassword, 
948                                     const char *oldpassword )
949 {
950         prs_struct qbuf, rbuf;
951         SAMR_Q_CHGPASSWD_USER q;
952         SAMR_R_CHGPASSWD_USER r;
953         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
954
955         uchar new_nt_password[516];
956         uchar new_lm_password[516];
957         uchar old_nt_hash[16];
958         uchar old_lanman_hash[16];
959         uchar old_nt_hash_enc[16];
960         uchar old_lanman_hash_enc[16];
961
962         uchar new_nt_hash[16];
963         uchar new_lanman_hash[16];
964
965         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
966
967         DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
968
969         ZERO_STRUCT(q);
970         ZERO_STRUCT(r);
971
972         /* Calculate the MD4 hash (NT compatible) of the password */
973         E_md4hash(oldpassword, old_nt_hash);
974         E_md4hash(newpassword, new_nt_hash);
975
976         if (lp_client_lanman_auth() 
977             && E_deshash(newpassword, new_lanman_hash) 
978             && E_deshash(oldpassword, old_lanman_hash)) {
979                 /* E_deshash returns false for 'long' passwords (> 14
980                    DOS chars).  This allows us to match Win2k, which
981                    does not store a LM hash for these passwords (which
982                    would reduce the effective password length to 14) */
983
984                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
985
986                 SamOEMhash( new_lm_password, old_nt_hash, 516);
987                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
988         } else {
989                 ZERO_STRUCT(new_lm_password);
990                 ZERO_STRUCT(old_lanman_hash_enc);
991         }
992
993         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
994         
995         SamOEMhash( new_nt_password, old_nt_hash, 516);
996         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
997
998         /* Marshall data and send request */
999
1000         init_samr_q_chgpasswd_user(&q, srv_name_slash, username, 
1001                                    new_nt_password, 
1002                                    old_nt_hash_enc, 
1003                                    new_lm_password,
1004                                    old_lanman_hash_enc);
1005
1006         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER,
1007                 q, r,
1008                 qbuf, rbuf,
1009                 samr_io_q_chgpasswd_user,
1010                 samr_io_r_chgpasswd_user,
1011                 NT_STATUS_UNSUCCESSFUL); 
1012
1013         /* Return output parameters */
1014
1015         if (!NT_STATUS_IS_OK(result = r.status)) {
1016                 goto done;
1017         }
1018
1019  done:
1020
1021         return result;
1022 }
1023
1024 /* User change password given blobs */
1025
1026 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
1027                                     TALLOC_CTX *mem_ctx, 
1028                                     const char *username, 
1029                                     DATA_BLOB new_nt_password,
1030                                     DATA_BLOB old_nt_hash_enc,
1031                                     DATA_BLOB new_lm_password,
1032                                     DATA_BLOB old_lm_hash_enc)
1033 {
1034         prs_struct qbuf, rbuf;
1035         SAMR_Q_CHGPASSWD_USER q;
1036         SAMR_R_CHGPASSWD_USER r;
1037         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1038
1039         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
1040
1041         DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
1042
1043         ZERO_STRUCT(q);
1044         ZERO_STRUCT(r);
1045
1046         /* Marshall data and send request */
1047
1048         init_samr_q_chgpasswd_user(&q, srv_name_slash, username, 
1049                                    new_nt_password.data, 
1050                                    old_nt_hash_enc.data, 
1051                                    new_lm_password.data,
1052                                    old_lm_hash_enc.data);
1053
1054         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER,
1055                 q, r,
1056                 qbuf, rbuf,
1057                 samr_io_q_chgpasswd_user,
1058                 samr_io_r_chgpasswd_user,
1059                 NT_STATUS_UNSUCCESSFUL); 
1060
1061         /* Return output parameters */
1062
1063         if (!NT_STATUS_IS_OK(result = r.status)) {
1064                 goto done;
1065         }
1066
1067  done:
1068
1069         return result;
1070 }
1071
1072
1073 /* change password 3 */
1074
1075 NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
1076                                 TALLOC_CTX *mem_ctx, 
1077                                 const char *username, 
1078                                 const char *newpassword, 
1079                                 const char *oldpassword,
1080                                 SAM_UNK_INFO_1 *info,
1081                                 SAMR_CHANGE_REJECT *reject)
1082 {
1083         prs_struct qbuf, rbuf;
1084         SAMR_Q_CHGPASSWD_USER3 q;
1085         SAMR_R_CHGPASSWD_USER3 r;
1086
1087         uchar new_nt_password[516];
1088         uchar new_lm_password[516];
1089         uchar old_nt_hash[16];
1090         uchar old_lanman_hash[16];
1091         uchar old_nt_hash_enc[16];
1092         uchar old_lanman_hash_enc[16];
1093
1094         uchar new_nt_hash[16];
1095         uchar new_lanman_hash[16];
1096
1097         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
1098
1099         DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
1100
1101         ZERO_STRUCT(q);
1102         ZERO_STRUCT(r);
1103
1104         /* Calculate the MD4 hash (NT compatible) of the password */
1105         E_md4hash(oldpassword, old_nt_hash);
1106         E_md4hash(newpassword, new_nt_hash);
1107
1108         if (lp_client_lanman_auth() 
1109             && E_deshash(newpassword, new_lanman_hash) 
1110             && E_deshash(oldpassword, old_lanman_hash)) {
1111                 /* E_deshash returns false for 'long' passwords (> 14
1112                    DOS chars).  This allows us to match Win2k, which
1113                    does not store a LM hash for these passwords (which
1114                    would reduce the effective password length to 14) */
1115
1116                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1117
1118                 SamOEMhash( new_lm_password, old_nt_hash, 516);
1119                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1120         } else {
1121                 ZERO_STRUCT(new_lm_password);
1122                 ZERO_STRUCT(old_lanman_hash_enc);
1123         }
1124
1125         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1126         
1127         SamOEMhash( new_nt_password, old_nt_hash, 516);
1128         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1129
1130         /* Marshall data and send request */
1131
1132         init_samr_q_chgpasswd_user3(&q, srv_name_slash, username, 
1133                                     new_nt_password, 
1134                                     old_nt_hash_enc, 
1135                                     new_lm_password,
1136                                     old_lanman_hash_enc);
1137         r.info = info;
1138         r.reject = reject;
1139
1140         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER3,
1141                 q, r,
1142                 qbuf, rbuf,
1143                 samr_io_q_chgpasswd_user3,
1144                 samr_io_r_chgpasswd_user3,
1145                 NT_STATUS_UNSUCCESSFUL); 
1146
1147         /* Return output parameters */
1148
1149         return r.status;
1150 }
1151
1152 /* This function returns the bizzare set of (max_entries, max_size) required
1153    for the QueryDisplayInfo RPC to actually work against a domain controller
1154    with large (10k and higher) numbers of users.  These values were 
1155    obtained by inspection using ethereal and NT4 running User Manager. */
1156
1157 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1158                                uint32 *max_size)
1159 {
1160         switch(loop_count) {
1161         case 0:
1162                 *max_entries = 512;
1163                 *max_size = 16383;
1164                 break;
1165         case 1:
1166                 *max_entries = 1024;
1167                 *max_size = 32766;
1168                 break;
1169         case 2:
1170                 *max_entries = 2048;
1171                 *max_size = 65532;
1172                 break;
1173         case 3:
1174                 *max_entries = 4096;
1175                 *max_size = 131064;
1176                 break;
1177         default:              /* loop_count >= 4 */
1178                 *max_entries = 4096;
1179                 *max_size = 131071;
1180                 break;
1181         }
1182 }                    
1183
1184 /* Query display info */
1185
1186 NTSTATUS rpccli_samr_query_dispinfo(struct rpc_pipe_client *cli,
1187                                     TALLOC_CTX *mem_ctx, 
1188                                     POLICY_HND *domain_pol, uint32 *start_idx,
1189                                     uint16 switch_value, uint32 *num_entries,
1190                                     uint32 max_entries, uint32 max_size,
1191                                     SAM_DISPINFO_CTR *ctr)
1192 {
1193         prs_struct qbuf, rbuf;
1194         SAMR_Q_QUERY_DISPINFO q;
1195         SAMR_R_QUERY_DISPINFO r;
1196         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1197
1198         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1199
1200         ZERO_STRUCT(q);
1201         ZERO_STRUCT(r);
1202
1203         *num_entries = 0;
1204
1205         /* Marshall data and send request */
1206
1207         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1208                                    *start_idx, max_entries, max_size);
1209
1210         r.ctr = ctr;
1211
1212         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DISPINFO,
1213                 q, r,
1214                 qbuf, rbuf,
1215                 samr_io_q_query_dispinfo,
1216                 samr_io_r_query_dispinfo,
1217                 NT_STATUS_UNSUCCESSFUL); 
1218
1219         /* Return output parameters */
1220
1221         result = r.status;
1222
1223         if (!NT_STATUS_IS_OK(result) &&
1224             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1225                 goto done;
1226         }
1227
1228         *num_entries = r.num_entries;
1229         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1230
1231  done:
1232         return result;
1233 }
1234
1235 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1236    looked up in one packet. */
1237
1238 NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
1239                                  TALLOC_CTX *mem_ctx, 
1240                                  POLICY_HND *domain_pol,
1241                                  uint32 num_rids, uint32 *rids, 
1242                                  uint32 *num_names, char ***names,
1243                                  uint32 **name_types)
1244 {
1245         prs_struct qbuf, rbuf;
1246         SAMR_Q_LOOKUP_RIDS q;
1247         SAMR_R_LOOKUP_RIDS r;
1248         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1249         uint32 i;
1250
1251         DEBUG(10,("cli_samr_lookup_rids\n"));
1252
1253         if (num_rids > 1000) {
1254                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1255                           "more than ~1000 rids are looked up at once.\n"));
1256         }
1257
1258         ZERO_STRUCT(q);
1259         ZERO_STRUCT(r);
1260
1261         /* Marshall data and send request */
1262
1263         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
1264
1265         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_RIDS,
1266                 q, r,
1267                 qbuf, rbuf,
1268                 samr_io_q_lookup_rids,
1269                 samr_io_r_lookup_rids,
1270                 NT_STATUS_UNSUCCESSFUL); 
1271
1272         /* Return output parameters */
1273
1274         result = r.status;
1275
1276         if (!NT_STATUS_IS_OK(result) &&
1277             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1278                 goto done;
1279
1280         if (r.num_names1 == 0) {
1281                 *num_names = 0;
1282                 *names = NULL;
1283                 goto done;
1284         }
1285
1286         *num_names = r.num_names1;
1287         *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1288         *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1289
1290         if ((*names == NULL) || (*name_types == NULL)) {
1291                 TALLOC_FREE(*names);
1292                 TALLOC_FREE(*name_types);
1293                 return NT_STATUS_NO_MEMORY;
1294         }
1295
1296         for (i = 0; i < r.num_names1; i++) {
1297                 fstring tmp;
1298
1299                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp));
1300                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1301                 (*name_types)[i] = r.type[i];
1302         }
1303
1304  done:
1305
1306         return result;
1307 }
1308
1309 /* Lookup names */
1310
1311 NTSTATUS rpccli_samr_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
1312                                POLICY_HND *domain_pol, uint32 flags,
1313                                uint32 num_names, const char **names,
1314                                uint32 *num_rids, uint32 **rids,
1315                                uint32 **rid_types)
1316 {
1317         prs_struct qbuf, rbuf;
1318         SAMR_Q_LOOKUP_NAMES q;
1319         SAMR_R_LOOKUP_NAMES r;
1320         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1321         uint32 i;
1322
1323         DEBUG(10,("cli_samr_lookup_names\n"));
1324
1325         ZERO_STRUCT(q);
1326         ZERO_STRUCT(r);
1327
1328         /* Marshall data and send request */
1329
1330         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1331                                  num_names, names);
1332
1333         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_NAMES,
1334                 q, r,
1335                 qbuf, rbuf,
1336                 samr_io_q_lookup_names,
1337                 samr_io_r_lookup_names,
1338                 NT_STATUS_UNSUCCESSFUL); 
1339
1340         /* Return output parameters */
1341
1342         if (!NT_STATUS_IS_OK(result = r.status)) {
1343                 goto done;
1344         }
1345
1346         if (r.num_rids1 == 0) {
1347                 *num_rids = 0;
1348                 goto done;
1349         }
1350
1351         *num_rids = r.num_rids1;
1352         *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1353         *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1354
1355         if ((*rids == NULL) || (*rid_types == NULL)) {
1356                 TALLOC_FREE(*rids);
1357                 TALLOC_FREE(*rid_types);
1358                 return NT_STATUS_NO_MEMORY;
1359         }
1360
1361         for (i = 0; i < r.num_rids1; i++) {
1362                 (*rids)[i] = r.rids[i];
1363                 (*rid_types)[i] = r.types[i];
1364         }
1365
1366  done:
1367
1368         return result;
1369 }
1370
1371 /* Set userinfo */
1372
1373 NTSTATUS rpccli_samr_set_userinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
1374                                const POLICY_HND *user_pol, uint16 switch_value,
1375                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1376 {
1377         prs_struct qbuf, rbuf;
1378         SAMR_Q_SET_USERINFO q;
1379         SAMR_R_SET_USERINFO r;
1380         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1381
1382         DEBUG(10,("cli_samr_set_userinfo\n"));
1383
1384         ZERO_STRUCT(q);
1385         ZERO_STRUCT(r);
1386
1387         if (!sess_key->length) {
1388                 DEBUG(1, ("No user session key\n"));
1389                 return NT_STATUS_NO_USER_SESSION_KEY;
1390         }
1391
1392         /* Initialise parse structures */
1393
1394         prs_init(&qbuf, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1395         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1396
1397         /* Marshall data and send request */
1398
1399         q.ctr = ctr;
1400
1401         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1402                                  ctr->info.id);
1403
1404         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_USERINFO,
1405                 q, r,
1406                 qbuf, rbuf,
1407                 samr_io_q_set_userinfo,
1408                 samr_io_r_set_userinfo,
1409                 NT_STATUS_UNSUCCESSFUL); 
1410
1411         /* Return output parameters */
1412
1413         if (!NT_STATUS_IS_OK(result = r.status)) {
1414                 goto done;
1415         }
1416
1417  done:
1418
1419         return result;
1420 }
1421
1422 /* Set userinfo2 */
1423
1424 NTSTATUS rpccli_samr_set_userinfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
1425                                    const POLICY_HND *user_pol, uint16 switch_value,
1426                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1427 {
1428         prs_struct qbuf, rbuf;
1429         SAMR_Q_SET_USERINFO2 q;
1430         SAMR_R_SET_USERINFO2 r;
1431         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1432
1433         DEBUG(10,("cli_samr_set_userinfo2\n"));
1434
1435         if (!sess_key->length) {
1436                 DEBUG(1, ("No user session key\n"));
1437                 return NT_STATUS_NO_USER_SESSION_KEY;
1438         }
1439
1440         ZERO_STRUCT(q);
1441         ZERO_STRUCT(r);
1442
1443         /* Marshall data and send request */
1444
1445         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1446
1447         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_USERINFO2,
1448                 q, r,
1449                 qbuf, rbuf,
1450                 samr_io_q_set_userinfo2,
1451                 samr_io_r_set_userinfo2,
1452                 NT_STATUS_UNSUCCESSFUL); 
1453
1454         /* Return output parameters */
1455
1456         if (!NT_STATUS_IS_OK(result = r.status)) {
1457                 goto done;
1458         }
1459
1460  done:
1461
1462         return result;
1463 }
1464
1465 /* Remove foreign SID */
1466
1467 NTSTATUS rpccli_samr_remove_sid_foreign_domain(struct rpc_pipe_client *cli, 
1468                                             TALLOC_CTX *mem_ctx, 
1469                                             POLICY_HND *user_pol,
1470                                             DOM_SID *sid)
1471 {
1472         prs_struct qbuf, rbuf;
1473         SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
1474         SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
1475         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1476
1477         DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
1478
1479         ZERO_STRUCT(q);
1480         ZERO_STRUCT(r);
1481
1482         /* Marshall data and send request */
1483
1484         init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
1485
1486         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN,
1487                 q, r,
1488                 qbuf, rbuf,
1489                 samr_io_q_remove_sid_foreign_domain,
1490                 samr_io_r_remove_sid_foreign_domain,
1491                 NT_STATUS_UNSUCCESSFUL); 
1492
1493         /* Return output parameters */
1494
1495         result = r.status;
1496
1497         return result;
1498 }
1499
1500 /* Lookup Domain Name */
1501
1502 NTSTATUS rpccli_samr_lookup_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1503                                 POLICY_HND *user_pol, char *domain_name, 
1504                                 DOM_SID *sid)
1505 {
1506         prs_struct qbuf, rbuf;
1507         SAMR_Q_LOOKUP_DOMAIN q;
1508         SAMR_R_LOOKUP_DOMAIN r;
1509         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1510
1511         DEBUG(10,("cli_samr_lookup_domain\n"));
1512
1513         ZERO_STRUCT(q);
1514         ZERO_STRUCT(r);
1515
1516         /* Marshall data and send request */
1517
1518         init_samr_q_lookup_domain(&q, user_pol, domain_name);
1519
1520         CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_DOMAIN,
1521                 q, r,
1522                 qbuf, rbuf,
1523                 samr_io_q_lookup_domain,
1524                 samr_io_r_lookup_domain,
1525                 NT_STATUS_UNSUCCESSFUL); 
1526
1527         /* Return output parameters */
1528
1529         result = r.status;
1530
1531         if (NT_STATUS_IS_OK(result))
1532                 sid_copy(sid, &r.dom_sid.sid);
1533
1534         return result;
1535 }