Merge Volker's fix.
[tprouty/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 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
31                           uint32 access_mask, POLICY_HND *connect_pol)
32 {
33         prs_struct qbuf, rbuf;
34         SAMR_Q_CONNECT q;
35         SAMR_R_CONNECT r;
36         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
37
38         DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
39
40         ZERO_STRUCT(q);
41         ZERO_STRUCT(r);
42
43         /* Initialise parse structures */
44
45         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
46         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
47
48         /* Marshall data and send request */
49
50         init_samr_q_connect(&q, cli->desthost, access_mask);
51
52         if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53             !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf))
54                 goto done;
55
56         /* Unmarshall response */
57
58         if (!samr_io_r_connect("", &r, &rbuf, 0))
59                 goto done;
60
61         /* Return output parameters */
62
63         if (NT_STATUS_IS_OK(result = r.status)) {
64                 *connect_pol = r.connect_pol;
65 #ifdef __INSURE__
66                 connect_pol->marker = malloc(1);
67 #endif
68         }
69
70  done:
71         prs_mem_free(&qbuf);
72         prs_mem_free(&rbuf);
73
74         return result;
75 }
76
77 /* Connect to SAMR database */
78
79 NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
80                            uint32 access_mask, POLICY_HND *connect_pol)
81 {
82         prs_struct qbuf, rbuf;
83         SAMR_Q_CONNECT4 q;
84         SAMR_R_CONNECT4 r;
85         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
86
87         DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
88
89         ZERO_STRUCT(q);
90         ZERO_STRUCT(r);
91
92         /* Initialise parse structures */
93
94         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
95         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
96
97         /* Marshall data and send request */
98
99         init_samr_q_connect4(&q, cli->desthost, access_mask);
100
101         if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
102             !rpc_api_pipe_req(cli, SAMR_CONNECT4, &qbuf, &rbuf))
103                 goto done;
104
105         /* Unmarshall response */
106
107         if (!samr_io_r_connect4("", &r, &rbuf, 0))
108                 goto done;
109
110         /* Return output parameters */
111
112         if (NT_STATUS_IS_OK(result = r.status)) {
113                 *connect_pol = r.connect_pol;
114 #ifdef __INSURE__
115                 connect_pol->marker = malloc(1);
116 #endif
117         }
118
119  done:
120         prs_mem_free(&qbuf);
121         prs_mem_free(&rbuf);
122
123         return result;
124 }
125
126 /* Close SAMR handle */
127
128 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
129                         POLICY_HND *connect_pol)
130 {
131         prs_struct qbuf, rbuf;
132         SAMR_Q_CLOSE_HND q;
133         SAMR_R_CLOSE_HND r;
134         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
135
136         DEBUG(10,("cli_samr_close\n"));
137
138         ZERO_STRUCT(q);
139         ZERO_STRUCT(r);
140
141         /* Initialise parse structures */
142
143         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
144         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
145
146         /* Marshall data and send request */
147
148         init_samr_q_close_hnd(&q, connect_pol);
149
150         if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
151             !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
152                 goto done;
153
154         /* Unmarshall response */
155
156         if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
157                 goto done;
158
159         /* Return output parameters */
160
161         if (NT_STATUS_IS_OK(result = r.status)) {
162 #ifdef __INSURE__
163                 SAFE_FREE(connect_pol->marker);
164 #endif
165                 *connect_pol = r.pol;
166         }
167
168  done:
169         prs_mem_free(&qbuf);
170         prs_mem_free(&rbuf);
171
172         return result;
173 }
174
175 /* Open handle on a domain */
176
177 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
178                               POLICY_HND *connect_pol, uint32 access_mask, 
179                               const DOM_SID *domain_sid, POLICY_HND *domain_pol)
180 {
181         prs_struct qbuf, rbuf;
182         SAMR_Q_OPEN_DOMAIN q;
183         SAMR_R_OPEN_DOMAIN r;
184         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
185
186         DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
187
188         ZERO_STRUCT(q);
189         ZERO_STRUCT(r);
190
191         /* Initialise parse structures */
192
193         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
194         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
195
196         /* Marshall data and send request */
197
198         init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
199
200         if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
201             !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
202                 goto done;
203
204         /* Unmarshall response */
205
206         if (!samr_io_r_open_domain("", &r, &rbuf, 0))
207                 goto done;
208
209         /* Return output parameters */
210
211         if (NT_STATUS_IS_OK(result = r.status)) {
212                 *domain_pol = r.domain_pol;
213 #ifdef __INSURE__
214                 domain_pol->marker = malloc(1);
215 #endif
216         }
217
218  done:
219         prs_mem_free(&qbuf);
220         prs_mem_free(&rbuf);
221
222         return result;
223 }
224
225 /* Open handle on a user */
226
227 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
228                             POLICY_HND *domain_pol, uint32 access_mask, 
229                             uint32 user_rid, POLICY_HND *user_pol)
230 {
231         prs_struct qbuf, rbuf;
232         SAMR_Q_OPEN_USER q;
233         SAMR_R_OPEN_USER r;
234         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
235
236         DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
237
238         ZERO_STRUCT(q);
239         ZERO_STRUCT(r);
240
241         /* Initialise parse structures */
242
243         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
244         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
245
246         /* Marshall data and send request */
247
248         init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
249
250         if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
251             !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
252                 goto done;
253
254         /* Unmarshall response */
255
256         if (!samr_io_r_open_user("", &r, &rbuf, 0))
257                 goto done;
258
259         /* Return output parameters */
260
261         if (NT_STATUS_IS_OK(result = r.status)) {
262                 *user_pol = r.user_pol;
263 #ifdef __INSURE__
264                 user_pol->marker = malloc(1);
265 #endif
266         }
267
268  done:
269         prs_mem_free(&qbuf);
270         prs_mem_free(&rbuf);
271
272         return result;
273 }
274
275 /* Open handle on a group */
276
277 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
278                              POLICY_HND *domain_pol, uint32 access_mask, 
279                              uint32 group_rid, POLICY_HND *group_pol)
280 {
281         prs_struct qbuf, rbuf;
282         SAMR_Q_OPEN_GROUP q;
283         SAMR_R_OPEN_GROUP r;
284         NTSTATUS result =  NT_STATUS_UNSUCCESSFUL;
285
286         DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
287
288         ZERO_STRUCT(q);
289         ZERO_STRUCT(r);
290
291         /* Initialise parse structures */
292
293         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
294         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
295
296         /* Marshall data and send request */
297
298         init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
299
300         if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
301             !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
302                 goto done;
303
304         /* Unmarshall response */
305
306         if (!samr_io_r_open_group("", &r, &rbuf, 0))
307                 goto done;
308
309         /* Return output parameters */
310
311         if (NT_STATUS_IS_OK(result = r.status)) {
312                 *group_pol = r.pol;
313 #ifdef __INSURE__
314                 group_pol->marker = malloc(1);
315 #endif
316         }
317
318  done:
319         prs_mem_free(&qbuf);
320         prs_mem_free(&rbuf);
321
322         return result;
323 }
324
325 /* Query user info */
326
327 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
328                                  POLICY_HND *user_pol, uint16 switch_value, 
329                                  SAM_USERINFO_CTR **ctr)
330 {
331         prs_struct qbuf, rbuf;
332         SAMR_Q_QUERY_USERINFO q;
333         SAMR_R_QUERY_USERINFO r;
334         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
335
336         DEBUG(10,("cli_samr_query_userinfo\n"));
337
338         ZERO_STRUCT(q);
339         ZERO_STRUCT(r);
340
341         /* Initialise parse structures */
342
343         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
344         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
345
346         /* Marshall data and send request */
347
348         init_samr_q_query_userinfo(&q, user_pol, switch_value);
349
350         if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
351             !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
352                 goto done;
353
354         /* Unmarshall response */
355
356         if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
357                 goto done;
358
359         /* Return output parameters */
360
361         result = r.status;
362         *ctr = r.ctr;
363
364  done:
365         prs_mem_free(&qbuf);
366         prs_mem_free(&rbuf);
367
368         return result;
369 }
370
371 /* Query group info */
372
373 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
374                                   POLICY_HND *group_pol, uint32 info_level, 
375                                   GROUP_INFO_CTR **ctr)
376 {
377         prs_struct qbuf, rbuf;
378         SAMR_Q_QUERY_GROUPINFO q;
379         SAMR_R_QUERY_GROUPINFO r;
380         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
381
382         DEBUG(10,("cli_samr_query_groupinfo\n"));
383
384         ZERO_STRUCT(q);
385         ZERO_STRUCT(r);
386
387         /* Initialise parse structures */
388
389         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
390         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
391
392         /* Marshall data and send request */
393
394         init_samr_q_query_groupinfo(&q, group_pol, info_level);
395
396         if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
397             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
398                 goto done;
399
400         /* Unmarshall response */
401
402         if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
403                 goto done;
404
405         *ctr = r.ctr;
406
407         /* Return output parameters */
408
409         result = r.status;
410
411  done:
412         prs_mem_free(&qbuf);
413         prs_mem_free(&rbuf);
414
415         return result;
416 }
417
418 /* Query user groups */
419
420 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
421                                    POLICY_HND *user_pol, uint32 *num_groups, 
422                                    DOM_GID **gid)
423 {
424         prs_struct qbuf, rbuf;
425         SAMR_Q_QUERY_USERGROUPS q;
426         SAMR_R_QUERY_USERGROUPS r;
427         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
428
429         DEBUG(10,("cli_samr_query_usergroups\n"));
430
431         ZERO_STRUCT(q);
432         ZERO_STRUCT(r);
433
434         /* Initialise parse structures */
435
436         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
437         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
438
439         /* Marshall data and send request */
440
441         init_samr_q_query_usergroups(&q, user_pol);
442
443         if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
444             !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
445                 goto done;
446
447         /* Unmarshall response */
448
449         if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
450                 goto done;
451
452         /* Return output parameters */
453
454         if (NT_STATUS_IS_OK(result = r.status)) {
455                 *num_groups = r.num_entries;
456                 *gid = r.gid;
457         }
458
459  done:
460         prs_mem_free(&qbuf);
461         prs_mem_free(&rbuf);
462
463         return result;
464 }
465
466 /* Query user aliases */
467
468 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
469                                    POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
470                                    uint32 *num_aliases, uint32 **als_rids)
471 {
472         prs_struct qbuf, rbuf;
473         SAMR_Q_QUERY_USERALIASES q;
474         SAMR_R_QUERY_USERALIASES r;
475         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
476         unsigned int ptr=1;
477         
478         DEBUG(10,("cli_samr_query_useraliases\n"));
479
480         ZERO_STRUCT(q);
481         ZERO_STRUCT(r);
482
483         /* Initialise parse structures */
484
485         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
486         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
487
488         /* Marshall data and send request */
489
490         init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
491
492         if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
493             !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
494                 goto done;
495
496         /* Unmarshall response */
497
498         if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
499                 goto done;
500
501         /* Return output parameters */
502
503         if (NT_STATUS_IS_OK(result = r.status)) {
504                 *num_aliases = r.num_entries;
505                 *als_rids = r.rid;
506         }
507
508  done:
509         prs_mem_free(&qbuf);
510         prs_mem_free(&rbuf);
511
512         return result;
513 }
514
515 /* Query user groups */
516
517 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
518                                  POLICY_HND *group_pol, uint32 *num_mem, 
519                                  uint32 **rid, uint32 **attr)
520 {
521         prs_struct qbuf, rbuf;
522         SAMR_Q_QUERY_GROUPMEM q;
523         SAMR_R_QUERY_GROUPMEM r;
524         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
525
526         DEBUG(10,("cli_samr_query_groupmem\n"));
527
528         ZERO_STRUCT(q);
529         ZERO_STRUCT(r);
530
531         /* Initialise parse structures */
532
533         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
534         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
535
536         /* Marshall data and send request */
537
538         init_samr_q_query_groupmem(&q, group_pol);
539
540         if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
541             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
542                 goto done;
543
544         /* Unmarshall response */
545
546         if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
547                 goto done;
548
549         /* Return output parameters */
550
551         if (NT_STATUS_IS_OK(result = r.status)) {
552                 *num_mem = r.num_entries;
553                 *rid = r.rid;
554                 *attr = r.attr;
555         }
556
557  done:
558         prs_mem_free(&qbuf);
559         prs_mem_free(&rbuf);
560
561         return result;
562 }
563
564 /**
565  * Enumerate domain users
566  *
567  * @param cli client state structure
568  * @param mem_ctx talloc context
569  * @param pol opened domain policy handle
570  * @param start_idx starting index of enumeration, returns context for
571                     next enumeration
572  * @param acb_mask account control bit mask (to enumerate some particular
573  *                 kind of accounts)
574  * @param size max acceptable size of response
575  * @param dom_users returned array of domain user names
576  * @param rids returned array of domain user RIDs
577  * @param num_dom_users numer returned entries
578  * 
579  * @return NTSTATUS returned in rpc response
580  **/
581 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
582                                  POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
583                                  uint32 size, char ***dom_users, uint32 **rids,
584                                  uint32 *num_dom_users)
585 {
586         prs_struct qbuf;
587         prs_struct rbuf;
588         SAMR_Q_ENUM_DOM_USERS q;
589         SAMR_R_ENUM_DOM_USERS r;
590         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
591         int i;
592         
593         DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
594
595         ZERO_STRUCT(q);
596         ZERO_STRUCT(r);
597         
598         /* always init this */
599         *num_dom_users = 0;
600         
601         /* Initialise parse structures */
602
603         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
604         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
605         
606         /* Fill query structure with parameters */
607
608         init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
609         
610         if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
611             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
612                 goto done;
613         }
614
615         /* unpack received stream */
616
617         if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
618                 goto done;
619         
620         result = r.status;
621
622         if (!NT_STATUS_IS_OK(result) &&
623             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
624                 goto done;
625         
626         *start_idx = r.next_idx;
627         *num_dom_users = r.num_entries2;
628
629         if (r.num_entries2) {
630                 /* allocate memory needed to return received data */    
631                 *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2);
632                 if (!*rids) {
633                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
634                         return NT_STATUS_NO_MEMORY;
635                 }
636                 
637                 *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2);
638                 if (!*dom_users) {
639                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
640                         return NT_STATUS_NO_MEMORY;
641                 }
642                 
643                 /* fill output buffers with rpc response */
644                 for (i = 0; i < r.num_entries2; i++) {
645                         fstring conv_buf;
646                         
647                         (*rids)[i] = r.sam[i].rid;
648                         unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
649                         (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
650                 }
651         }
652         
653 done:
654         prs_mem_free(&qbuf);
655         prs_mem_free(&rbuf);
656         
657         return result;
658 }
659
660 /* Enumerate domain groups */
661
662 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
663                                   POLICY_HND *pol, uint32 *start_idx, 
664                                   uint32 size, struct acct_info **dom_groups,
665                                   uint32 *num_dom_groups)
666 {
667         prs_struct qbuf, rbuf;
668         SAMR_Q_ENUM_DOM_GROUPS q;
669         SAMR_R_ENUM_DOM_GROUPS r;
670         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
671         uint32 name_idx, i;
672
673         DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
674
675         ZERO_STRUCT(q);
676         ZERO_STRUCT(r);
677
678         /* Initialise parse structures */
679
680         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
681         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
682
683         /* Marshall data and send request */
684
685         init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
686
687         if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
688             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
689                 goto done;
690
691         /* Unmarshall response */
692
693         if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
694                 goto done;
695
696         /* Return output parameters */
697
698         result = r.status;
699
700         if (!NT_STATUS_IS_OK(result) &&
701             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
702                 goto done;
703
704         *num_dom_groups = r.num_entries2;
705
706         if (*num_dom_groups == 0)
707                 goto done;
708
709         if (!((*dom_groups) = (struct acct_info *)
710               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
711                 result = NT_STATUS_NO_MEMORY;
712                 goto done;
713         }
714
715         memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
716
717         name_idx = 0;
718
719         for (i = 0; i < *num_dom_groups; i++) {
720
721                 (*dom_groups)[i].rid = r.sam[i].rid;
722
723                 if (r.sam[i].hdr_name.buffer) {
724                         unistr2_to_ascii((*dom_groups)[i].acct_name,
725                                          &r.uni_grp_name[name_idx],
726                                          sizeof(fstring) - 1);
727                         name_idx++;
728                 }
729
730                 *start_idx = r.next_idx;
731         }
732
733  done:
734         prs_mem_free(&qbuf);
735         prs_mem_free(&rbuf);
736
737         return result;
738 }
739
740 /* Enumerate domain groups */
741
742 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
743                                   POLICY_HND *pol, uint32 *start_idx, 
744                                   uint32 size, struct acct_info **dom_aliases,
745                                   uint32 *num_dom_aliases)
746 {
747         prs_struct qbuf, rbuf;
748         SAMR_Q_ENUM_DOM_ALIASES q;
749         SAMR_R_ENUM_DOM_ALIASES r;
750         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
751         uint32 name_idx, i;
752
753         DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
754
755         ZERO_STRUCT(q);
756         ZERO_STRUCT(r);
757
758         /* Initialise parse structures */
759
760         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
761         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
762
763         /* Marshall data and send request */
764
765         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
766
767         if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
768             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
769                 goto done;
770         }
771
772         /* Unmarshall response */
773
774         if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
775                 goto done;
776         }
777
778         /* Return output parameters */
779
780         result = r.status;
781
782         if (!NT_STATUS_IS_OK(result) &&
783             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
784                 goto done;
785         }
786
787         *num_dom_aliases = r.num_entries2;
788
789         if (*num_dom_aliases == 0)
790                 goto done;
791
792         if (!((*dom_aliases) = (struct acct_info *)
793               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_aliases))) {
794                 result = NT_STATUS_NO_MEMORY;
795                 goto done;
796         }
797
798         memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
799
800         name_idx = 0;
801
802         for (i = 0; i < *num_dom_aliases; i++) {
803
804                 (*dom_aliases)[i].rid = r.sam[i].rid;
805
806                 if (r.sam[i].hdr_name.buffer) {
807                         unistr2_to_ascii((*dom_aliases)[i].acct_name,
808                                          &r.uni_grp_name[name_idx],
809                                          sizeof(fstring) - 1);
810                         name_idx++;
811                 }
812
813                 *start_idx = r.next_idx;
814         }
815
816  done:
817         prs_mem_free(&qbuf);
818         prs_mem_free(&rbuf);
819
820         return result;
821 }
822
823 /* Query alias members */
824
825 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
826                                  POLICY_HND *alias_pol, uint32 *num_mem, 
827                                  DOM_SID **sids)
828 {
829         prs_struct qbuf, rbuf;
830         SAMR_Q_QUERY_ALIASMEM q;
831         SAMR_R_QUERY_ALIASMEM r;
832         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
833         uint32 i;
834
835         DEBUG(10,("cli_samr_query_aliasmem\n"));
836
837         ZERO_STRUCT(q);
838         ZERO_STRUCT(r);
839
840         /* Initialise parse structures */
841
842         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
843         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
844
845         /* Marshall data and send request */
846
847         init_samr_q_query_aliasmem(&q, alias_pol);
848
849         if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
850             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
851                 goto done;
852         }
853
854         /* Unmarshall response */
855
856         if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
857                 goto done;
858         }
859
860         /* Return output parameters */
861
862         if (!NT_STATUS_IS_OK(result = r.status)) {
863                 goto done;
864         }
865
866         *num_mem = r.num_sids;
867
868         if (*num_mem == 0) {
869                 *sids = NULL;
870                 result = NT_STATUS_OK;
871                 goto done;
872         }
873
874         if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
875                 result = NT_STATUS_UNSUCCESSFUL;
876                 goto done;
877         }
878
879         for (i = 0; i < *num_mem; i++) {
880                 (*sids)[i] = r.sid[i].sid;
881         }
882
883  done:
884         prs_mem_free(&qbuf);
885         prs_mem_free(&rbuf);
886
887         return result;
888 }
889
890 /* Open handle on an alias */
891
892 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
893                              POLICY_HND *domain_pol, uint32 access_mask, 
894                              uint32 alias_rid, POLICY_HND *alias_pol)
895 {
896         prs_struct qbuf, rbuf;
897         SAMR_Q_OPEN_ALIAS q;
898         SAMR_R_OPEN_ALIAS r;
899         NTSTATUS result;
900
901         DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
902
903         ZERO_STRUCT(q);
904         ZERO_STRUCT(r);
905
906         /* Initialise parse structures */
907
908         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
909         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
910
911         /* Marshall data and send request */
912
913         init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
914
915         if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
916             !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
917                 result = NT_STATUS_UNSUCCESSFUL;
918                 goto done;
919         }
920
921         /* Unmarshall response */
922
923         if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
924                 result = NT_STATUS_UNSUCCESSFUL;
925                 goto done;
926         }
927
928         /* Return output parameters */
929
930         if (NT_STATUS_IS_OK(result = r.status)) {
931                 *alias_pol = r.pol;
932 #ifdef __INSURE__
933                 alias_pol->marker = malloc(1);
934 #endif
935         }
936
937  done:
938         prs_mem_free(&qbuf);
939         prs_mem_free(&rbuf);
940
941         return result;
942 }
943
944 /* Query alias info */
945
946 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
947                                    POLICY_HND *alias_pol, uint16 switch_value,
948                                    ALIAS_INFO_CTR *ctr)
949 {
950         prs_struct qbuf, rbuf;
951         SAMR_Q_QUERY_ALIASINFO q;
952         SAMR_R_QUERY_ALIASINFO r;
953         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
954
955         DEBUG(10,("cli_samr_query_dom_info\n"));
956
957         ZERO_STRUCT(q);
958         ZERO_STRUCT(r);
959
960         /* Initialise parse structures */
961
962         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
963         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
964
965         /* Marshall data and send request */
966
967         init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
968
969         if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
970             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
971                 goto done;
972         }
973
974         /* Unmarshall response */
975
976         if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
977                 goto done;
978         }
979
980         /* Return output parameters */
981
982         if (!NT_STATUS_IS_OK(result = r.status)) {
983                 goto done;
984         }
985
986         *ctr = r.ctr;
987
988  done:
989         prs_mem_free(&qbuf);
990         prs_mem_free(&rbuf);
991
992         return result;
993 }
994
995 /* Query domain info */
996
997 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
998                                  POLICY_HND *domain_pol, uint16 switch_value,
999                                  SAM_UNK_CTR *ctr)
1000 {
1001         prs_struct qbuf, rbuf;
1002         SAMR_Q_QUERY_DOMAIN_INFO q;
1003         SAMR_R_QUERY_DOMAIN_INFO r;
1004         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1005
1006         DEBUG(10,("cli_samr_query_dom_info\n"));
1007
1008         ZERO_STRUCT(q);
1009         ZERO_STRUCT(r);
1010
1011         /* Initialise parse structures */
1012
1013         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1014         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1015
1016         /* Marshall data and send request */
1017
1018         init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1019
1020         if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1021             !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1022                 goto done;
1023         }
1024
1025         /* Unmarshall response */
1026
1027         r.ctr = ctr;
1028
1029         if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1030                 goto done;
1031         }
1032
1033         /* Return output parameters */
1034
1035         if (!NT_STATUS_IS_OK(result = r.status)) {
1036                 goto done;
1037         }
1038
1039  done:
1040         prs_mem_free(&qbuf);
1041         prs_mem_free(&rbuf);
1042
1043         return result;
1044 }
1045
1046 /* This function returns the bizzare set of (max_entries, max_size) required
1047    for the QueryDisplayInfo RPC to actually work against a domain controller
1048    with large (10k and higher) numbers of users.  These values were 
1049    obtained by inspection using ethereal and NT4 running User Manager. */
1050
1051 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1052                                uint32 *max_size)
1053 {
1054         switch(loop_count) {
1055         case 0:
1056                 *max_entries = 512;
1057                 *max_size = 16383;
1058                 break;
1059         case 1:
1060                 *max_entries = 1024;
1061                 *max_size = 32766;
1062                 break;
1063         case 2:
1064                 *max_entries = 2048;
1065                 *max_size = 65532;
1066                 break;
1067         case 3:
1068                 *max_entries = 4096;
1069                 *max_size = 131064;
1070                 break;
1071         default:              /* loop_count >= 4 */
1072                 *max_entries = 4096;
1073                 *max_size = 131071;
1074                 break;
1075         }
1076 }                    
1077
1078 /* Query display info */
1079
1080 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1081                                  POLICY_HND *domain_pol, uint32 *start_idx,
1082                                  uint16 switch_value, uint32 *num_entries,
1083                                  uint32 max_entries, uint32 max_size,
1084                                  SAM_DISPINFO_CTR *ctr)
1085 {
1086         prs_struct qbuf, rbuf;
1087         SAMR_Q_QUERY_DISPINFO q;
1088         SAMR_R_QUERY_DISPINFO r;
1089         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1090
1091         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1092
1093         ZERO_STRUCT(q);
1094         ZERO_STRUCT(r);
1095
1096         *num_entries = 0;
1097
1098         /* Initialise parse structures */
1099
1100         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1101         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1102
1103         /* Marshall data and send request */
1104
1105         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1106                                    *start_idx, max_entries, max_size);
1107
1108         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1109             !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1110                 goto done;
1111         }
1112
1113         /* Unmarshall response */
1114
1115         r.ctr = ctr;
1116
1117         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1118                 goto done;
1119         }
1120
1121         /* Return output parameters */
1122
1123         result = r.status;
1124
1125         if (!NT_STATUS_IS_OK(result) &&
1126             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1127                 goto done;
1128         }
1129
1130         *num_entries = r.num_entries;
1131         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1132
1133  done:
1134         prs_mem_free(&qbuf);
1135         prs_mem_free(&rbuf);
1136
1137         return result;
1138 }
1139
1140 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1141    looked up in one packet. */
1142
1143 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1144                               POLICY_HND *domain_pol, uint32 flags,
1145                               uint32 num_rids, uint32 *rids, 
1146                               uint32 *num_names, char ***names,
1147                               uint32 **name_types)
1148 {
1149         prs_struct qbuf, rbuf;
1150         SAMR_Q_LOOKUP_RIDS q;
1151         SAMR_R_LOOKUP_RIDS r;
1152         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1153         uint32 i;
1154
1155         DEBUG(10,("cli_samr_lookup_rids\n"));
1156
1157         if (num_rids > 1000) {
1158                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1159                           "more than ~1000 rids are looked up at once.\n"));
1160         }
1161
1162         ZERO_STRUCT(q);
1163         ZERO_STRUCT(r);
1164
1165         /* Initialise parse structures */
1166
1167         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1168         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1169
1170         /* Marshall data and send request */
1171
1172         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1173                                 num_rids, rids);
1174
1175         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1176             !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1177                 goto done;
1178         }
1179
1180         /* Unmarshall response */
1181
1182         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1183                 goto done;
1184         }
1185
1186         /* Return output parameters */
1187
1188         if (!NT_STATUS_IS_OK(result = r.status)) {
1189                 goto done;
1190         }
1191
1192         if (r.num_names1 == 0) {
1193                 *num_names = 0;
1194                 *names = NULL;
1195                 goto done;
1196         }
1197
1198         *num_names = r.num_names1;
1199         *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
1200         *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
1201
1202         for (i = 0; i < r.num_names1; i++) {
1203                 fstring tmp;
1204
1205                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1206                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1207                 (*name_types)[i] = r.type[i];
1208         }
1209
1210  done:
1211         prs_mem_free(&qbuf);
1212         prs_mem_free(&rbuf);
1213
1214         return result;
1215 }
1216
1217 /* Lookup names */
1218
1219 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1220                                POLICY_HND *domain_pol, uint32 flags,
1221                                uint32 num_names, const char **names,
1222                                uint32 *num_rids, uint32 **rids,
1223                                uint32 **rid_types)
1224 {
1225         prs_struct qbuf, rbuf;
1226         SAMR_Q_LOOKUP_NAMES q;
1227         SAMR_R_LOOKUP_NAMES r;
1228         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1229         uint32 i;
1230
1231         DEBUG(10,("cli_samr_lookup_names\n"));
1232
1233         ZERO_STRUCT(q);
1234         ZERO_STRUCT(r);
1235
1236         /* Initialise parse structures */
1237
1238         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1239         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1240
1241         /* Marshall data and send request */
1242
1243         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1244                                  num_names, names);
1245
1246         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1247             !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1248                 goto done;
1249         }
1250
1251         /* Unmarshall response */
1252
1253         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1254                 goto done;
1255         }
1256
1257         /* Return output parameters */
1258
1259         if (!NT_STATUS_IS_OK(result = r.status)) {
1260                 goto done;
1261         }
1262
1263         if (r.num_rids1 == 0) {
1264                 *num_rids = 0;
1265                 goto done;
1266         }
1267
1268         *num_rids = r.num_rids1;
1269         *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1270         *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1271
1272         for (i = 0; i < r.num_rids1; i++) {
1273                 (*rids)[i] = r.rids[i];
1274                 (*rid_types)[i] = r.types[i];
1275         }
1276
1277  done:
1278         prs_mem_free(&qbuf);
1279         prs_mem_free(&rbuf);
1280
1281         return result;
1282 }
1283
1284 /* Create a domain user */
1285
1286 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1287                                   POLICY_HND *domain_pol, const char *acct_name,
1288                                   uint32 acb_info, uint32 unknown, 
1289                                   POLICY_HND *user_pol, uint32 *rid)
1290 {
1291         prs_struct qbuf, rbuf;
1292         SAMR_Q_CREATE_USER q;
1293         SAMR_R_CREATE_USER r;
1294         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1295
1296         DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1297
1298         ZERO_STRUCT(q);
1299         ZERO_STRUCT(r);
1300
1301         /* Initialise parse structures */
1302
1303         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1304         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1305
1306         /* Marshall data and send request */
1307
1308         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1309
1310         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1311             !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1312                 goto done;
1313         }
1314
1315         /* Unmarshall response */
1316
1317         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1318                 goto done;
1319         }
1320
1321         /* Return output parameters */
1322
1323         if (!NT_STATUS_IS_OK(result = r.status)) {
1324                 goto done;
1325         }
1326
1327         if (user_pol)
1328                 *user_pol = r.user_pol;
1329
1330         if (rid)
1331                 *rid = r.user_rid;
1332
1333  done:
1334         prs_mem_free(&qbuf);
1335         prs_mem_free(&rbuf);
1336
1337         return result;
1338 }
1339
1340 /* Set userinfo */
1341
1342 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1343                                POLICY_HND *user_pol, uint16 switch_value,
1344                                uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1345 {
1346         prs_struct qbuf, rbuf;
1347         SAMR_Q_SET_USERINFO q;
1348         SAMR_R_SET_USERINFO r;
1349         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1350
1351         DEBUG(10,("cli_samr_set_userinfo\n"));
1352
1353         ZERO_STRUCT(q);
1354         ZERO_STRUCT(r);
1355
1356         /* Initialise parse structures */
1357
1358         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1359         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1360
1361         /* Marshall data and send request */
1362
1363         q.ctr = ctr;
1364
1365         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1366                                  ctr->info.id);
1367
1368         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1369             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1370                 goto done;
1371         }
1372
1373         /* Unmarshall response */
1374
1375         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1376                 goto done;
1377         }
1378
1379         /* Return output parameters */
1380
1381         if (!NT_STATUS_IS_OK(result = r.status)) {
1382                 goto done;
1383         }
1384
1385  done:
1386         prs_mem_free(&qbuf);
1387         prs_mem_free(&rbuf);
1388
1389         return result;
1390 }
1391
1392 /* Set userinfo2 */
1393
1394 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1395                                 POLICY_HND *user_pol, uint16 switch_value,
1396                                 uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1397 {
1398         prs_struct qbuf, rbuf;
1399         SAMR_Q_SET_USERINFO2 q;
1400         SAMR_R_SET_USERINFO2 r;
1401         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1402
1403         DEBUG(10,("cli_samr_set_userinfo2\n"));
1404
1405         ZERO_STRUCT(q);
1406         ZERO_STRUCT(r);
1407
1408         /* Initialise parse structures */
1409
1410         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1411         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1412
1413         /* Marshall data and send request */
1414
1415         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1416
1417         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1418             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1419                 goto done;
1420         }
1421
1422         /* Unmarshall response */
1423
1424         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1425                 goto done;
1426         }
1427
1428         /* Return output parameters */
1429
1430         if (!NT_STATUS_IS_OK(result = r.status)) {
1431                 goto done;
1432         }
1433
1434  done:
1435         prs_mem_free(&qbuf);
1436         prs_mem_free(&rbuf);
1437
1438         return result;
1439 }
1440
1441 /* Delete domain user */
1442
1443 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1444                                   POLICY_HND *user_pol)
1445 {
1446         prs_struct qbuf, rbuf;
1447         SAMR_Q_DELETE_DOM_USER q;
1448         SAMR_R_DELETE_DOM_USER r;
1449         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1450
1451         DEBUG(10,("cli_samr_delete_dom_user\n"));
1452
1453         ZERO_STRUCT(q);
1454         ZERO_STRUCT(r);
1455
1456         /* Initialise parse structures */
1457
1458         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1459         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1460
1461         /* Marshall data and send request */
1462
1463         init_samr_q_delete_dom_user(&q, user_pol);
1464
1465         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1466             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1467                 goto done;
1468         }
1469
1470         /* Unmarshall response */
1471
1472         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1473                 goto done;
1474         }
1475
1476         /* Return output parameters */
1477
1478         result = r.status;
1479
1480  done:
1481         prs_mem_free(&qbuf);
1482         prs_mem_free(&rbuf);
1483
1484         return result;
1485 }
1486
1487 /* Query user security object */
1488
1489 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1490                                  POLICY_HND *user_pol, uint16 switch_value, 
1491                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1492 {
1493         prs_struct qbuf, rbuf;
1494         SAMR_Q_QUERY_SEC_OBJ q;
1495         SAMR_R_QUERY_SEC_OBJ r;
1496         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1497
1498         DEBUG(10,("cli_samr_query_sec_obj\n"));
1499
1500         ZERO_STRUCT(q);
1501         ZERO_STRUCT(r);
1502
1503         /* Initialise parse structures */
1504
1505         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1506         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1507
1508         /* Marshall data and send request */
1509
1510         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1511
1512         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1513             !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1514                 goto done;
1515         }
1516
1517         /* Unmarshall response */
1518
1519         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1520                 goto done;
1521         }
1522
1523         /* Return output parameters */
1524
1525         result = r.status;
1526         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1527
1528  done:
1529         prs_mem_free(&qbuf);
1530         prs_mem_free(&rbuf);
1531
1532         return result;
1533 }
1534
1535 /* Get domain password info */
1536
1537 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1538                                  uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
1539 {
1540         prs_struct qbuf, rbuf;
1541         SAMR_Q_GET_DOM_PWINFO q;
1542         SAMR_R_GET_DOM_PWINFO r;
1543         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1544
1545         DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
1546
1547         ZERO_STRUCT(q);
1548         ZERO_STRUCT(r);
1549
1550         /* Initialise parse structures */
1551
1552         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1553         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1554
1555         /* Marshall data and send request */
1556
1557         init_samr_q_get_dom_pwinfo(&q, cli->desthost);
1558
1559         if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
1560             !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
1561                 goto done;
1562
1563         /* Unmarshall response */
1564
1565         if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
1566                 goto done;
1567
1568         /* Return output parameters */
1569
1570         result = r.status;
1571
1572         if (NT_STATUS_IS_OK(result)) {
1573                 if (unk_0)
1574                         *unk_0 = r.unk_0;
1575                 if (unk_1)
1576                         *unk_1 = r.unk_1;
1577                 if (unk_2)
1578                         *unk_2 = r.unk_2;
1579         }
1580
1581  done:
1582         prs_mem_free(&qbuf);
1583         prs_mem_free(&rbuf);
1584
1585         return result;
1586 }
1587
1588 /* Lookup Domain Name */
1589
1590 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1591                                 POLICY_HND *user_pol, char *domain_name, 
1592                                 DOM_SID *sid)
1593 {
1594         prs_struct qbuf, rbuf;
1595         SAMR_Q_LOOKUP_DOMAIN q;
1596         SAMR_R_LOOKUP_DOMAIN r;
1597         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1598
1599         DEBUG(10,("cli_samr_lookup_domain\n"));
1600
1601         ZERO_STRUCT(q);
1602         ZERO_STRUCT(r);
1603
1604         /* Initialise parse structures */
1605
1606         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1607         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1608
1609         /* Marshall data and send request */
1610
1611         init_samr_q_lookup_domain(&q, user_pol, domain_name);
1612
1613         if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
1614             !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
1615                 goto done;
1616
1617         /* Unmarshall response */
1618
1619         if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
1620                 goto done;
1621
1622         /* Return output parameters */
1623
1624         result = r.status;
1625
1626         if (NT_STATUS_IS_OK(result))
1627                 sid_copy(sid, &r.dom_sid.sid);
1628
1629  done:
1630         prs_mem_free(&qbuf);
1631         prs_mem_free(&rbuf);
1632
1633         return result;
1634 }