(merge from 3.0)
[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 /* User change password */
1047
1048 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1049                                  const char *username, 
1050                                  const char *newpassword, 
1051                                  const char *oldpassword )
1052 {
1053         prs_struct qbuf, rbuf;
1054         SAMR_Q_CHGPASSWD_USER q;
1055         SAMR_R_CHGPASSWD_USER r;
1056         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1057
1058         uchar new_nt_password[516];
1059         uchar new_lm_password[516];
1060         uchar old_nt_hash[16];
1061         uchar old_lanman_hash[16];
1062         uchar old_nt_hash_enc[16];
1063         uchar old_lanman_hash_enc[16];
1064
1065         uchar new_nt_hash[16];
1066         uchar new_lanman_hash[16];
1067
1068         DEBUG(10,("cli_samr_query_dom_info\n"));
1069
1070         ZERO_STRUCT(q);
1071         ZERO_STRUCT(r);
1072
1073         /* Calculate the MD4 hash (NT compatible) of the password */
1074         E_md4hash(oldpassword, old_nt_hash);
1075         E_md4hash(newpassword, new_nt_hash);
1076
1077         if (lp_client_lanman_auth() 
1078             && E_deshash(newpassword, new_lanman_hash) 
1079             && E_deshash(oldpassword, old_lanman_hash)) {
1080                 /* E_deshash returns false for 'long' passwords (> 14
1081                    DOS chars).  This allows us to match Win2k, which
1082                    does not store a LM hash for these passwords (which
1083                    would reduce the effective password length to 14) */
1084
1085                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1086
1087                 SamOEMhash( new_lm_password, old_nt_hash, 516);
1088                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1089         } else {
1090                 ZERO_STRUCT(new_lm_password);
1091                 ZERO_STRUCT(old_lanman_hash_enc);
1092         }
1093
1094         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1095         
1096         SamOEMhash( new_nt_password, old_nt_hash, 516);
1097         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1098
1099         /* Initialise parse structures */
1100
1101         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1102         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1103
1104         /* Marshall data and send request */
1105
1106         init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, 
1107                                    new_nt_password, 
1108                                    old_nt_hash_enc, 
1109                                    new_lm_password,
1110                                    old_lanman_hash_enc);
1111
1112         if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1113             !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1114                 goto done;
1115         }
1116
1117         /* Unmarshall response */
1118
1119         if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1120                 goto done;
1121         }
1122
1123         /* Return output parameters */
1124
1125         if (!NT_STATUS_IS_OK(result = r.status)) {
1126                 goto done;
1127         }
1128
1129  done:
1130         prs_mem_free(&qbuf);
1131         prs_mem_free(&rbuf);
1132
1133         return result;
1134 }
1135
1136 /* This function returns the bizzare set of (max_entries, max_size) required
1137    for the QueryDisplayInfo RPC to actually work against a domain controller
1138    with large (10k and higher) numbers of users.  These values were 
1139    obtained by inspection using ethereal and NT4 running User Manager. */
1140
1141 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1142                                uint32 *max_size)
1143 {
1144         switch(loop_count) {
1145         case 0:
1146                 *max_entries = 512;
1147                 *max_size = 16383;
1148                 break;
1149         case 1:
1150                 *max_entries = 1024;
1151                 *max_size = 32766;
1152                 break;
1153         case 2:
1154                 *max_entries = 2048;
1155                 *max_size = 65532;
1156                 break;
1157         case 3:
1158                 *max_entries = 4096;
1159                 *max_size = 131064;
1160                 break;
1161         default:              /* loop_count >= 4 */
1162                 *max_entries = 4096;
1163                 *max_size = 131071;
1164                 break;
1165         }
1166 }                    
1167
1168 /* Query display info */
1169
1170 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1171                                  POLICY_HND *domain_pol, uint32 *start_idx,
1172                                  uint16 switch_value, uint32 *num_entries,
1173                                  uint32 max_entries, uint32 max_size,
1174                                  SAM_DISPINFO_CTR *ctr)
1175 {
1176         prs_struct qbuf, rbuf;
1177         SAMR_Q_QUERY_DISPINFO q;
1178         SAMR_R_QUERY_DISPINFO r;
1179         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1180
1181         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1182
1183         ZERO_STRUCT(q);
1184         ZERO_STRUCT(r);
1185
1186         *num_entries = 0;
1187
1188         /* Initialise parse structures */
1189
1190         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1191         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1192
1193         /* Marshall data and send request */
1194
1195         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1196                                    *start_idx, max_entries, max_size);
1197
1198         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1199             !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1200                 goto done;
1201         }
1202
1203         /* Unmarshall response */
1204
1205         r.ctr = ctr;
1206
1207         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1208                 goto done;
1209         }
1210
1211         /* Return output parameters */
1212
1213         result = r.status;
1214
1215         if (!NT_STATUS_IS_OK(result) &&
1216             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1217                 goto done;
1218         }
1219
1220         *num_entries = r.num_entries;
1221         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1222
1223  done:
1224         prs_mem_free(&qbuf);
1225         prs_mem_free(&rbuf);
1226
1227         return result;
1228 }
1229
1230 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1231    looked up in one packet. */
1232
1233 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1234                               POLICY_HND *domain_pol, uint32 flags,
1235                               uint32 num_rids, uint32 *rids, 
1236                               uint32 *num_names, char ***names,
1237                               uint32 **name_types)
1238 {
1239         prs_struct qbuf, rbuf;
1240         SAMR_Q_LOOKUP_RIDS q;
1241         SAMR_R_LOOKUP_RIDS r;
1242         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1243         uint32 i;
1244
1245         DEBUG(10,("cli_samr_lookup_rids\n"));
1246
1247         if (num_rids > 1000) {
1248                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1249                           "more than ~1000 rids are looked up at once.\n"));
1250         }
1251
1252         ZERO_STRUCT(q);
1253         ZERO_STRUCT(r);
1254
1255         /* Initialise parse structures */
1256
1257         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1258         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1259
1260         /* Marshall data and send request */
1261
1262         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1263                                 num_rids, rids);
1264
1265         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1266             !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1267                 goto done;
1268         }
1269
1270         /* Unmarshall response */
1271
1272         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1273                 goto done;
1274         }
1275
1276         /* Return output parameters */
1277
1278         if (!NT_STATUS_IS_OK(result = r.status)) {
1279                 goto done;
1280         }
1281
1282         if (r.num_names1 == 0) {
1283                 *num_names = 0;
1284                 *names = NULL;
1285                 goto done;
1286         }
1287
1288         *num_names = r.num_names1;
1289         *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
1290         *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
1291
1292         for (i = 0; i < r.num_names1; i++) {
1293                 fstring tmp;
1294
1295                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1296                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1297                 (*name_types)[i] = r.type[i];
1298         }
1299
1300  done:
1301         prs_mem_free(&qbuf);
1302         prs_mem_free(&rbuf);
1303
1304         return result;
1305 }
1306
1307 /* Lookup names */
1308
1309 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1310                                POLICY_HND *domain_pol, uint32 flags,
1311                                uint32 num_names, const char **names,
1312                                uint32 *num_rids, uint32 **rids,
1313                                uint32 **rid_types)
1314 {
1315         prs_struct qbuf, rbuf;
1316         SAMR_Q_LOOKUP_NAMES q;
1317         SAMR_R_LOOKUP_NAMES r;
1318         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1319         uint32 i;
1320
1321         DEBUG(10,("cli_samr_lookup_names\n"));
1322
1323         ZERO_STRUCT(q);
1324         ZERO_STRUCT(r);
1325
1326         /* Initialise parse structures */
1327
1328         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1329         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1330
1331         /* Marshall data and send request */
1332
1333         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1334                                  num_names, names);
1335
1336         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1337             !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1338                 goto done;
1339         }
1340
1341         /* Unmarshall response */
1342
1343         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1344                 goto done;
1345         }
1346
1347         /* Return output parameters */
1348
1349         if (!NT_STATUS_IS_OK(result = r.status)) {
1350                 goto done;
1351         }
1352
1353         if (r.num_rids1 == 0) {
1354                 *num_rids = 0;
1355                 goto done;
1356         }
1357
1358         *num_rids = r.num_rids1;
1359         *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1360         *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1361
1362         for (i = 0; i < r.num_rids1; i++) {
1363                 (*rids)[i] = r.rids[i];
1364                 (*rid_types)[i] = r.types[i];
1365         }
1366
1367  done:
1368         prs_mem_free(&qbuf);
1369         prs_mem_free(&rbuf);
1370
1371         return result;
1372 }
1373
1374 /* Create a domain user */
1375
1376 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1377                                   POLICY_HND *domain_pol, const char *acct_name,
1378                                   uint32 acb_info, uint32 unknown, 
1379                                   POLICY_HND *user_pol, uint32 *rid)
1380 {
1381         prs_struct qbuf, rbuf;
1382         SAMR_Q_CREATE_USER q;
1383         SAMR_R_CREATE_USER r;
1384         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1385
1386         DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1387
1388         ZERO_STRUCT(q);
1389         ZERO_STRUCT(r);
1390
1391         /* Initialise parse structures */
1392
1393         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1394         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1395
1396         /* Marshall data and send request */
1397
1398         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1399
1400         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1401             !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1402                 goto done;
1403         }
1404
1405         /* Unmarshall response */
1406
1407         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1408                 goto done;
1409         }
1410
1411         /* Return output parameters */
1412
1413         if (!NT_STATUS_IS_OK(result = r.status)) {
1414                 goto done;
1415         }
1416
1417         if (user_pol)
1418                 *user_pol = r.user_pol;
1419
1420         if (rid)
1421                 *rid = r.user_rid;
1422
1423  done:
1424         prs_mem_free(&qbuf);
1425         prs_mem_free(&rbuf);
1426
1427         return result;
1428 }
1429
1430 /* Set userinfo */
1431
1432 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1433                                POLICY_HND *user_pol, uint16 switch_value,
1434                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1435 {
1436         prs_struct qbuf, rbuf;
1437         SAMR_Q_SET_USERINFO q;
1438         SAMR_R_SET_USERINFO r;
1439         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1440
1441         DEBUG(10,("cli_samr_set_userinfo\n"));
1442
1443         ZERO_STRUCT(q);
1444         ZERO_STRUCT(r);
1445
1446         if (!sess_key->length) {
1447                 DEBUG(1, ("No user session key\n"));
1448                 return NT_STATUS_NO_USER_SESSION_KEY;
1449         }
1450
1451         /* Initialise parse structures */
1452
1453         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1454         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1455
1456         /* Marshall data and send request */
1457
1458         q.ctr = ctr;
1459
1460         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1461                                  ctr->info.id);
1462
1463         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1464             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1465                 goto done;
1466         }
1467
1468         /* Unmarshall response */
1469
1470         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1471                 goto done;
1472         }
1473
1474         /* Return output parameters */
1475
1476         if (!NT_STATUS_IS_OK(result = r.status)) {
1477                 goto done;
1478         }
1479
1480  done:
1481         prs_mem_free(&qbuf);
1482         prs_mem_free(&rbuf);
1483
1484         return result;
1485 }
1486
1487 /* Set userinfo2 */
1488
1489 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1490                                 POLICY_HND *user_pol, uint16 switch_value,
1491                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1492 {
1493         prs_struct qbuf, rbuf;
1494         SAMR_Q_SET_USERINFO2 q;
1495         SAMR_R_SET_USERINFO2 r;
1496         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1497
1498         DEBUG(10,("cli_samr_set_userinfo2\n"));
1499
1500         if (!sess_key->length) {
1501                 DEBUG(1, ("No user session key\n"));
1502                 return NT_STATUS_NO_USER_SESSION_KEY;
1503         }
1504
1505         ZERO_STRUCT(q);
1506         ZERO_STRUCT(r);
1507
1508         /* Initialise parse structures */
1509
1510         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1511         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1512
1513         /* Marshall data and send request */
1514
1515         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1516
1517         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1518             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1519                 goto done;
1520         }
1521
1522         /* Unmarshall response */
1523
1524         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1525                 goto done;
1526         }
1527
1528         /* Return output parameters */
1529
1530         if (!NT_STATUS_IS_OK(result = r.status)) {
1531                 goto done;
1532         }
1533
1534  done:
1535         prs_mem_free(&qbuf);
1536         prs_mem_free(&rbuf);
1537
1538         return result;
1539 }
1540
1541 /* Delete domain user */
1542
1543 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1544                                   POLICY_HND *user_pol)
1545 {
1546         prs_struct qbuf, rbuf;
1547         SAMR_Q_DELETE_DOM_USER q;
1548         SAMR_R_DELETE_DOM_USER r;
1549         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1550
1551         DEBUG(10,("cli_samr_delete_dom_user\n"));
1552
1553         ZERO_STRUCT(q);
1554         ZERO_STRUCT(r);
1555
1556         /* Initialise parse structures */
1557
1558         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1559         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1560
1561         /* Marshall data and send request */
1562
1563         init_samr_q_delete_dom_user(&q, user_pol);
1564
1565         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1566             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1567                 goto done;
1568         }
1569
1570         /* Unmarshall response */
1571
1572         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1573                 goto done;
1574         }
1575
1576         /* Return output parameters */
1577
1578         result = r.status;
1579
1580  done:
1581         prs_mem_free(&qbuf);
1582         prs_mem_free(&rbuf);
1583
1584         return result;
1585 }
1586
1587 /* Query user security object */
1588
1589 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1590                                  POLICY_HND *user_pol, uint16 switch_value, 
1591                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1592 {
1593         prs_struct qbuf, rbuf;
1594         SAMR_Q_QUERY_SEC_OBJ q;
1595         SAMR_R_QUERY_SEC_OBJ r;
1596         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1597
1598         DEBUG(10,("cli_samr_query_sec_obj\n"));
1599
1600         ZERO_STRUCT(q);
1601         ZERO_STRUCT(r);
1602
1603         /* Initialise parse structures */
1604
1605         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1606         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1607
1608         /* Marshall data and send request */
1609
1610         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1611
1612         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1613             !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1614                 goto done;
1615         }
1616
1617         /* Unmarshall response */
1618
1619         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1620                 goto done;
1621         }
1622
1623         /* Return output parameters */
1624
1625         result = r.status;
1626         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1627
1628  done:
1629         prs_mem_free(&qbuf);
1630         prs_mem_free(&rbuf);
1631
1632         return result;
1633 }
1634
1635 /* Get domain password info */
1636
1637 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1638                                  uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
1639 {
1640         prs_struct qbuf, rbuf;
1641         SAMR_Q_GET_DOM_PWINFO q;
1642         SAMR_R_GET_DOM_PWINFO r;
1643         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1644
1645         DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
1646
1647         ZERO_STRUCT(q);
1648         ZERO_STRUCT(r);
1649
1650         /* Initialise parse structures */
1651
1652         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1653         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1654
1655         /* Marshall data and send request */
1656
1657         init_samr_q_get_dom_pwinfo(&q, cli->desthost);
1658
1659         if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
1660             !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
1661                 goto done;
1662
1663         /* Unmarshall response */
1664
1665         if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
1666                 goto done;
1667
1668         /* Return output parameters */
1669
1670         result = r.status;
1671
1672         if (NT_STATUS_IS_OK(result)) {
1673                 if (unk_0)
1674                         *unk_0 = r.unk_0;
1675                 if (unk_1)
1676                         *unk_1 = r.unk_1;
1677                 if (unk_2)
1678                         *unk_2 = r.unk_2;
1679         }
1680
1681  done:
1682         prs_mem_free(&qbuf);
1683         prs_mem_free(&rbuf);
1684
1685         return result;
1686 }
1687
1688 /* Lookup Domain Name */
1689
1690 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1691                                 POLICY_HND *user_pol, char *domain_name, 
1692                                 DOM_SID *sid)
1693 {
1694         prs_struct qbuf, rbuf;
1695         SAMR_Q_LOOKUP_DOMAIN q;
1696         SAMR_R_LOOKUP_DOMAIN r;
1697         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1698
1699         DEBUG(10,("cli_samr_lookup_domain\n"));
1700
1701         ZERO_STRUCT(q);
1702         ZERO_STRUCT(r);
1703
1704         /* Initialise parse structures */
1705
1706         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1707         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1708
1709         /* Marshall data and send request */
1710
1711         init_samr_q_lookup_domain(&q, user_pol, domain_name);
1712
1713         if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
1714             !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
1715                 goto done;
1716
1717         /* Unmarshall response */
1718
1719         if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
1720                 goto done;
1721
1722         /* Return output parameters */
1723
1724         result = r.status;
1725
1726         if (NT_STATUS_IS_OK(result))
1727                 sid_copy(sid, &r.dom_sid.sid);
1728
1729  done:
1730         prs_mem_free(&qbuf);
1731         prs_mem_free(&rbuf);
1732
1733         return result;
1734 }