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