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