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