missed one on BUG 1195; make sure to set the private * to NULL
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_samr.c
blobd534745d25a504d61d25280c421315f8eb418f8d
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
4 Copyright (C) Tim Potter 2000-2001,
5 Copyright (C) Andrew Tridgell 1992-1997,2000,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
7 Copyright (C) Paul Ashton 1997,2000,
8 Copyright (C) Elrond 2000,
9 Copyright (C) Rafal Szczesniak 2002.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "includes.h"
28 /* Connect to SAMR database */
30 NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
31 uint32 access_mask, POLICY_HND *connect_pol)
33 prs_struct qbuf, rbuf;
34 SAMR_Q_CONNECT q;
35 SAMR_R_CONNECT r;
36 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
38 DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
40 ZERO_STRUCT(q);
41 ZERO_STRUCT(r);
43 /* Initialise parse structures */
45 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
46 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
48 /* Marshall data and send request */
50 init_samr_q_connect(&q, cli->desthost, access_mask);
52 if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53 !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf))
54 goto done;
56 /* Unmarshall response */
58 if (!samr_io_r_connect("", &r, &rbuf, 0))
59 goto done;
61 /* Return output parameters */
63 if (NT_STATUS_IS_OK(result = r.status)) {
64 *connect_pol = r.connect_pol;
65 #ifdef __INSURE__
66 connect_pol->marker = malloc(1);
67 #endif
70 done:
71 prs_mem_free(&qbuf);
72 prs_mem_free(&rbuf);
74 return result;
77 /* Connect to SAMR database */
79 NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
80 uint32 access_mask, POLICY_HND *connect_pol)
82 prs_struct qbuf, rbuf;
83 SAMR_Q_CONNECT4 q;
84 SAMR_R_CONNECT4 r;
85 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
87 DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
89 ZERO_STRUCT(q);
90 ZERO_STRUCT(r);
92 /* Initialise parse structures */
94 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
95 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
97 /* Marshall data and send request */
99 init_samr_q_connect4(&q, cli->desthost, access_mask);
101 if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
102 !rpc_api_pipe_req(cli, SAMR_CONNECT4, &qbuf, &rbuf))
103 goto done;
105 /* Unmarshall response */
107 if (!samr_io_r_connect4("", &r, &rbuf, 0))
108 goto done;
110 /* Return output parameters */
112 if (NT_STATUS_IS_OK(result = r.status)) {
113 *connect_pol = r.connect_pol;
114 #ifdef __INSURE__
115 connect_pol->marker = malloc(1);
116 #endif
119 done:
120 prs_mem_free(&qbuf);
121 prs_mem_free(&rbuf);
123 return result;
126 /* Close SAMR handle */
128 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
129 POLICY_HND *connect_pol)
131 prs_struct qbuf, rbuf;
132 SAMR_Q_CLOSE_HND q;
133 SAMR_R_CLOSE_HND r;
134 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
136 DEBUG(10,("cli_samr_close\n"));
138 ZERO_STRUCT(q);
139 ZERO_STRUCT(r);
141 /* Initialise parse structures */
143 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
144 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
146 /* Marshall data and send request */
148 init_samr_q_close_hnd(&q, connect_pol);
150 if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
151 !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
152 goto done;
154 /* Unmarshall response */
156 if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
157 goto done;
159 /* Return output parameters */
161 if (NT_STATUS_IS_OK(result = r.status)) {
162 #ifdef __INSURE__
163 SAFE_FREE(connect_pol->marker);
164 #endif
165 *connect_pol = r.pol;
168 done:
169 prs_mem_free(&qbuf);
170 prs_mem_free(&rbuf);
172 return result;
175 /* Open handle on a domain */
177 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
178 POLICY_HND *connect_pol, uint32 access_mask,
179 const DOM_SID *domain_sid, POLICY_HND *domain_pol)
181 prs_struct qbuf, rbuf;
182 SAMR_Q_OPEN_DOMAIN q;
183 SAMR_R_OPEN_DOMAIN r;
184 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
186 DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
188 ZERO_STRUCT(q);
189 ZERO_STRUCT(r);
191 /* Initialise parse structures */
193 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
194 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
196 /* Marshall data and send request */
198 init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
200 if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
201 !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
202 goto done;
204 /* Unmarshall response */
206 if (!samr_io_r_open_domain("", &r, &rbuf, 0))
207 goto done;
209 /* Return output parameters */
211 if (NT_STATUS_IS_OK(result = r.status)) {
212 *domain_pol = r.domain_pol;
213 #ifdef __INSURE__
214 domain_pol->marker = malloc(1);
215 #endif
218 done:
219 prs_mem_free(&qbuf);
220 prs_mem_free(&rbuf);
222 return result;
225 /* Open handle on a user */
227 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
228 POLICY_HND *domain_pol, uint32 access_mask,
229 uint32 user_rid, POLICY_HND *user_pol)
231 prs_struct qbuf, rbuf;
232 SAMR_Q_OPEN_USER q;
233 SAMR_R_OPEN_USER r;
234 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
236 DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
238 ZERO_STRUCT(q);
239 ZERO_STRUCT(r);
241 /* Initialise parse structures */
243 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
244 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
246 /* Marshall data and send request */
248 init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
250 if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
251 !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
252 goto done;
254 /* Unmarshall response */
256 if (!samr_io_r_open_user("", &r, &rbuf, 0))
257 goto done;
259 /* Return output parameters */
261 if (NT_STATUS_IS_OK(result = r.status)) {
262 *user_pol = r.user_pol;
263 #ifdef __INSURE__
264 user_pol->marker = malloc(1);
265 #endif
268 done:
269 prs_mem_free(&qbuf);
270 prs_mem_free(&rbuf);
272 return result;
275 /* Open handle on a group */
277 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
278 POLICY_HND *domain_pol, uint32 access_mask,
279 uint32 group_rid, POLICY_HND *group_pol)
281 prs_struct qbuf, rbuf;
282 SAMR_Q_OPEN_GROUP q;
283 SAMR_R_OPEN_GROUP r;
284 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
286 DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
288 ZERO_STRUCT(q);
289 ZERO_STRUCT(r);
291 /* Initialise parse structures */
293 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
294 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
296 /* Marshall data and send request */
298 init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
300 if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
301 !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
302 goto done;
304 /* Unmarshall response */
306 if (!samr_io_r_open_group("", &r, &rbuf, 0))
307 goto done;
309 /* Return output parameters */
311 if (NT_STATUS_IS_OK(result = r.status)) {
312 *group_pol = r.pol;
313 #ifdef __INSURE__
314 group_pol->marker = malloc(1);
315 #endif
318 done:
319 prs_mem_free(&qbuf);
320 prs_mem_free(&rbuf);
322 return result;
325 /* Create domain group */
327 NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
328 POLICY_HND *domain_pol,
329 const char *group_name,
330 uint32 access_mask, POLICY_HND *group_pol)
332 prs_struct qbuf, rbuf;
333 SAMR_Q_CREATE_DOM_GROUP q;
334 SAMR_R_CREATE_DOM_GROUP r;
335 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
337 DEBUG(10,("cli_samr_create_dom_group\n"));
339 ZERO_STRUCT(q);
340 ZERO_STRUCT(r);
342 /* Initialise parse structures */
344 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
345 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
347 /* Marshall data and send request */
349 init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
351 if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
352 !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
353 goto done;
355 /* Unmarshall response */
357 if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
358 goto done;
360 /* Return output parameters */
362 result = r.status;
364 if (NT_STATUS_IS_OK(result))
365 *group_pol = r.pol;
367 done:
368 prs_mem_free(&qbuf);
369 prs_mem_free(&rbuf);
371 return result;
374 /* Add a domain group member */
376 NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
377 POLICY_HND *group_pol, uint32 rid)
379 prs_struct qbuf, rbuf;
380 SAMR_Q_ADD_GROUPMEM q;
381 SAMR_R_ADD_GROUPMEM r;
382 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
384 DEBUG(10,("cli_samr_add_groupmem\n"));
386 ZERO_STRUCT(q);
387 ZERO_STRUCT(r);
389 /* Initialise parse structures */
391 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
392 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
394 /* Marshall data and send request */
396 init_samr_q_add_groupmem(&q, group_pol, rid);
398 if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
399 !rpc_api_pipe_req(cli, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
400 goto done;
402 /* Unmarshall response */
404 if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
405 goto done;
407 /* Return output parameters */
409 result = r.status;
411 done:
412 prs_mem_free(&qbuf);
413 prs_mem_free(&rbuf);
415 return result;
418 /* Delete a domain group member */
420 NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
421 POLICY_HND *group_pol, uint32 rid)
423 prs_struct qbuf, rbuf;
424 SAMR_Q_DEL_GROUPMEM q;
425 SAMR_R_DEL_GROUPMEM r;
426 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
428 DEBUG(10,("cli_samr_del_groupmem\n"));
430 ZERO_STRUCT(q);
431 ZERO_STRUCT(r);
433 /* Initialise parse structures */
435 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
436 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
438 /* Marshall data and send request */
440 init_samr_q_del_groupmem(&q, group_pol, rid);
442 if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
443 !rpc_api_pipe_req(cli, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
444 goto done;
446 /* Unmarshall response */
448 if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
449 goto done;
451 /* Return output parameters */
453 result = r.status;
455 done:
456 prs_mem_free(&qbuf);
457 prs_mem_free(&rbuf);
459 return result;
462 /* Query user info */
464 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
465 POLICY_HND *user_pol, uint16 switch_value,
466 SAM_USERINFO_CTR **ctr)
468 prs_struct qbuf, rbuf;
469 SAMR_Q_QUERY_USERINFO q;
470 SAMR_R_QUERY_USERINFO r;
471 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
473 DEBUG(10,("cli_samr_query_userinfo\n"));
475 ZERO_STRUCT(q);
476 ZERO_STRUCT(r);
478 /* Initialise parse structures */
480 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
481 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
483 /* Marshall data and send request */
485 init_samr_q_query_userinfo(&q, user_pol, switch_value);
487 if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
488 !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
489 goto done;
491 /* Unmarshall response */
493 if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
494 goto done;
496 /* Return output parameters */
498 result = r.status;
499 *ctr = r.ctr;
501 done:
502 prs_mem_free(&qbuf);
503 prs_mem_free(&rbuf);
505 return result;
508 /* Set group info */
510 NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
511 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
513 prs_struct qbuf, rbuf;
514 SAMR_Q_SET_GROUPINFO q;
515 SAMR_R_SET_GROUPINFO r;
516 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
518 DEBUG(10,("cli_samr_set_groupinfo\n"));
520 ZERO_STRUCT(q);
521 ZERO_STRUCT(r);
523 /* Initialise parse structures */
525 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
526 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
528 /* Marshall data and send request */
530 init_samr_q_set_groupinfo(&q, group_pol, ctr);
532 if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
533 !rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
534 goto done;
536 /* Unmarshall response */
538 if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
539 goto done;
541 /* Return output parameters */
543 result = r.status;
545 done:
546 prs_mem_free(&qbuf);
547 prs_mem_free(&rbuf);
549 return result;
552 /* Query group info */
554 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
555 POLICY_HND *group_pol, uint32 info_level,
556 GROUP_INFO_CTR **ctr)
558 prs_struct qbuf, rbuf;
559 SAMR_Q_QUERY_GROUPINFO q;
560 SAMR_R_QUERY_GROUPINFO r;
561 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
563 DEBUG(10,("cli_samr_query_groupinfo\n"));
565 ZERO_STRUCT(q);
566 ZERO_STRUCT(r);
568 /* Initialise parse structures */
570 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
571 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
573 /* Marshall data and send request */
575 init_samr_q_query_groupinfo(&q, group_pol, info_level);
577 if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
578 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
579 goto done;
581 /* Unmarshall response */
583 if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
584 goto done;
586 *ctr = r.ctr;
588 /* Return output parameters */
590 result = r.status;
592 done:
593 prs_mem_free(&qbuf);
594 prs_mem_free(&rbuf);
596 return result;
599 /* Query user groups */
601 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
602 POLICY_HND *user_pol, uint32 *num_groups,
603 DOM_GID **gid)
605 prs_struct qbuf, rbuf;
606 SAMR_Q_QUERY_USERGROUPS q;
607 SAMR_R_QUERY_USERGROUPS r;
608 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
610 DEBUG(10,("cli_samr_query_usergroups\n"));
612 ZERO_STRUCT(q);
613 ZERO_STRUCT(r);
615 /* Initialise parse structures */
617 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
618 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
620 /* Marshall data and send request */
622 init_samr_q_query_usergroups(&q, user_pol);
624 if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
625 !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
626 goto done;
628 /* Unmarshall response */
630 if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
631 goto done;
633 /* Return output parameters */
635 if (NT_STATUS_IS_OK(result = r.status)) {
636 *num_groups = r.num_entries;
637 *gid = r.gid;
640 done:
641 prs_mem_free(&qbuf);
642 prs_mem_free(&rbuf);
644 return result;
647 /* Set alias info */
649 NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
650 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
652 prs_struct qbuf, rbuf;
653 SAMR_Q_SET_ALIASINFO q;
654 SAMR_R_SET_ALIASINFO r;
655 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
657 DEBUG(10,("cli_samr_set_aliasinfo\n"));
659 ZERO_STRUCT(q);
660 ZERO_STRUCT(r);
662 /* Initialise parse structures */
664 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
665 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
667 /* Marshall data and send request */
669 init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
671 if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
672 !rpc_api_pipe_req(cli, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
673 goto done;
675 /* Unmarshall response */
677 if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
678 goto done;
680 /* Return output parameters */
682 result = r.status;
684 done:
685 prs_mem_free(&qbuf);
686 prs_mem_free(&rbuf);
688 return result;
691 /* Query user aliases */
693 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
694 POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
695 uint32 *num_aliases, uint32 **als_rids)
697 prs_struct qbuf, rbuf;
698 SAMR_Q_QUERY_USERALIASES q;
699 SAMR_R_QUERY_USERALIASES r;
700 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
701 unsigned int ptr=1;
703 DEBUG(10,("cli_samr_query_useraliases\n"));
705 ZERO_STRUCT(q);
706 ZERO_STRUCT(r);
708 /* Initialise parse structures */
710 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
711 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
713 /* Marshall data and send request */
715 init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
717 if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
718 !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
719 goto done;
721 /* Unmarshall response */
723 if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
724 goto done;
726 /* Return output parameters */
728 if (NT_STATUS_IS_OK(result = r.status)) {
729 *num_aliases = r.num_entries;
730 *als_rids = r.rid;
733 done:
734 prs_mem_free(&qbuf);
735 prs_mem_free(&rbuf);
737 return result;
740 /* Query user groups */
742 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
743 POLICY_HND *group_pol, uint32 *num_mem,
744 uint32 **rid, uint32 **attr)
746 prs_struct qbuf, rbuf;
747 SAMR_Q_QUERY_GROUPMEM q;
748 SAMR_R_QUERY_GROUPMEM r;
749 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
751 DEBUG(10,("cli_samr_query_groupmem\n"));
753 ZERO_STRUCT(q);
754 ZERO_STRUCT(r);
756 /* Initialise parse structures */
758 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
759 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
761 /* Marshall data and send request */
763 init_samr_q_query_groupmem(&q, group_pol);
765 if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
766 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
767 goto done;
769 /* Unmarshall response */
771 if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
772 goto done;
774 /* Return output parameters */
776 if (NT_STATUS_IS_OK(result = r.status)) {
777 *num_mem = r.num_entries;
778 *rid = r.rid;
779 *attr = r.attr;
782 done:
783 prs_mem_free(&qbuf);
784 prs_mem_free(&rbuf);
786 return result;
790 * Enumerate domain users
792 * @param cli client state structure
793 * @param mem_ctx talloc context
794 * @param pol opened domain policy handle
795 * @param start_idx starting index of enumeration, returns context for
796 next enumeration
797 * @param acb_mask account control bit mask (to enumerate some particular
798 * kind of accounts)
799 * @param size max acceptable size of response
800 * @param dom_users returned array of domain user names
801 * @param rids returned array of domain user RIDs
802 * @param num_dom_users numer returned entries
804 * @return NTSTATUS returned in rpc response
806 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
807 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
808 uint32 size, char ***dom_users, uint32 **rids,
809 uint32 *num_dom_users)
811 prs_struct qbuf;
812 prs_struct rbuf;
813 SAMR_Q_ENUM_DOM_USERS q;
814 SAMR_R_ENUM_DOM_USERS r;
815 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
816 int i;
818 DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
820 ZERO_STRUCT(q);
821 ZERO_STRUCT(r);
823 /* always init this */
824 *num_dom_users = 0;
826 /* Initialise parse structures */
828 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
829 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
831 /* Fill query structure with parameters */
833 init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
835 if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
836 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
837 goto done;
840 /* unpack received stream */
842 if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
843 goto done;
845 result = r.status;
847 if (!NT_STATUS_IS_OK(result) &&
848 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
849 goto done;
851 *start_idx = r.next_idx;
852 *num_dom_users = r.num_entries2;
854 if (r.num_entries2) {
855 /* allocate memory needed to return received data */
856 *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2);
857 if (!*rids) {
858 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
859 return NT_STATUS_NO_MEMORY;
862 *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2);
863 if (!*dom_users) {
864 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
865 return NT_STATUS_NO_MEMORY;
868 /* fill output buffers with rpc response */
869 for (i = 0; i < r.num_entries2; i++) {
870 fstring conv_buf;
872 (*rids)[i] = r.sam[i].rid;
873 unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
874 (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
878 done:
879 prs_mem_free(&qbuf);
880 prs_mem_free(&rbuf);
882 return result;
885 /* Enumerate domain groups */
887 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
888 POLICY_HND *pol, uint32 *start_idx,
889 uint32 size, struct acct_info **dom_groups,
890 uint32 *num_dom_groups)
892 prs_struct qbuf, rbuf;
893 SAMR_Q_ENUM_DOM_GROUPS q;
894 SAMR_R_ENUM_DOM_GROUPS r;
895 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
896 uint32 name_idx, i;
898 DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
900 ZERO_STRUCT(q);
901 ZERO_STRUCT(r);
903 /* Initialise parse structures */
905 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
906 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
908 /* Marshall data and send request */
910 init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
912 if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
913 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
914 goto done;
916 /* Unmarshall response */
918 if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
919 goto done;
921 /* Return output parameters */
923 result = r.status;
925 if (!NT_STATUS_IS_OK(result) &&
926 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
927 goto done;
929 *num_dom_groups = r.num_entries2;
931 if (*num_dom_groups == 0)
932 goto done;
934 if (!((*dom_groups) = (struct acct_info *)
935 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
936 result = NT_STATUS_NO_MEMORY;
937 goto done;
940 memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
942 name_idx = 0;
944 for (i = 0; i < *num_dom_groups; i++) {
946 (*dom_groups)[i].rid = r.sam[i].rid;
948 if (r.sam[i].hdr_name.buffer) {
949 unistr2_to_ascii((*dom_groups)[i].acct_name,
950 &r.uni_grp_name[name_idx],
951 sizeof(fstring) - 1);
952 name_idx++;
955 *start_idx = r.next_idx;
958 done:
959 prs_mem_free(&qbuf);
960 prs_mem_free(&rbuf);
962 return result;
965 /* Enumerate domain groups */
967 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
968 POLICY_HND *pol, uint32 *start_idx,
969 uint32 size, struct acct_info **dom_aliases,
970 uint32 *num_dom_aliases)
972 prs_struct qbuf, rbuf;
973 SAMR_Q_ENUM_DOM_ALIASES q;
974 SAMR_R_ENUM_DOM_ALIASES r;
975 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
976 uint32 name_idx, i;
978 DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
980 ZERO_STRUCT(q);
981 ZERO_STRUCT(r);
983 /* Initialise parse structures */
985 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
986 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
988 /* Marshall data and send request */
990 init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
992 if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
993 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
994 goto done;
997 /* Unmarshall response */
999 if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1000 goto done;
1003 /* Return output parameters */
1005 result = r.status;
1007 if (!NT_STATUS_IS_OK(result) &&
1008 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1009 goto done;
1012 *num_dom_aliases = r.num_entries2;
1014 if (*num_dom_aliases == 0)
1015 goto done;
1017 if (!((*dom_aliases) = (struct acct_info *)
1018 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_aliases))) {
1019 result = NT_STATUS_NO_MEMORY;
1020 goto done;
1023 memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1025 name_idx = 0;
1027 for (i = 0; i < *num_dom_aliases; i++) {
1029 (*dom_aliases)[i].rid = r.sam[i].rid;
1031 if (r.sam[i].hdr_name.buffer) {
1032 unistr2_to_ascii((*dom_aliases)[i].acct_name,
1033 &r.uni_grp_name[name_idx],
1034 sizeof(fstring) - 1);
1035 name_idx++;
1038 *start_idx = r.next_idx;
1041 done:
1042 prs_mem_free(&qbuf);
1043 prs_mem_free(&rbuf);
1045 return result;
1048 /* Query alias members */
1050 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1051 POLICY_HND *alias_pol, uint32 *num_mem,
1052 DOM_SID **sids)
1054 prs_struct qbuf, rbuf;
1055 SAMR_Q_QUERY_ALIASMEM q;
1056 SAMR_R_QUERY_ALIASMEM r;
1057 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1058 uint32 i;
1060 DEBUG(10,("cli_samr_query_aliasmem\n"));
1062 ZERO_STRUCT(q);
1063 ZERO_STRUCT(r);
1065 /* Initialise parse structures */
1067 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1068 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1070 /* Marshall data and send request */
1072 init_samr_q_query_aliasmem(&q, alias_pol);
1074 if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1075 !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1076 goto done;
1079 /* Unmarshall response */
1081 if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1082 goto done;
1085 /* Return output parameters */
1087 if (!NT_STATUS_IS_OK(result = r.status)) {
1088 goto done;
1091 *num_mem = r.num_sids;
1093 if (*num_mem == 0) {
1094 *sids = NULL;
1095 result = NT_STATUS_OK;
1096 goto done;
1099 if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
1100 result = NT_STATUS_UNSUCCESSFUL;
1101 goto done;
1104 for (i = 0; i < *num_mem; i++) {
1105 (*sids)[i] = r.sid[i].sid;
1108 done:
1109 prs_mem_free(&qbuf);
1110 prs_mem_free(&rbuf);
1112 return result;
1115 /* Open handle on an alias */
1117 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1118 POLICY_HND *domain_pol, uint32 access_mask,
1119 uint32 alias_rid, POLICY_HND *alias_pol)
1121 prs_struct qbuf, rbuf;
1122 SAMR_Q_OPEN_ALIAS q;
1123 SAMR_R_OPEN_ALIAS r;
1124 NTSTATUS result;
1126 DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1128 ZERO_STRUCT(q);
1129 ZERO_STRUCT(r);
1131 /* Initialise parse structures */
1133 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1134 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1136 /* Marshall data and send request */
1138 init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1140 if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1141 !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1142 result = NT_STATUS_UNSUCCESSFUL;
1143 goto done;
1146 /* Unmarshall response */
1148 if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1149 result = NT_STATUS_UNSUCCESSFUL;
1150 goto done;
1153 /* Return output parameters */
1155 if (NT_STATUS_IS_OK(result = r.status)) {
1156 *alias_pol = r.pol;
1157 #ifdef __INSURE__
1158 alias_pol->marker = malloc(1);
1159 #endif
1162 done:
1163 prs_mem_free(&qbuf);
1164 prs_mem_free(&rbuf);
1166 return result;
1169 /* Create an alias */
1171 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1172 POLICY_HND *domain_pol, const char *name,
1173 POLICY_HND *alias_pol)
1175 prs_struct qbuf, rbuf;
1176 SAMR_Q_CREATE_DOM_ALIAS q;
1177 SAMR_R_CREATE_DOM_ALIAS r;
1178 NTSTATUS result;
1180 DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1182 ZERO_STRUCT(q);
1183 ZERO_STRUCT(r);
1185 /* Initialise parse structures */
1187 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1188 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1190 /* Marshall data and send request */
1192 init_samr_q_create_dom_alias(&q, domain_pol, name);
1194 if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1195 !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1196 result = NT_STATUS_UNSUCCESSFUL;
1197 goto done;
1200 /* Unmarshall response */
1202 if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1203 result = NT_STATUS_UNSUCCESSFUL;
1204 goto done;
1207 /* Return output parameters */
1209 if (NT_STATUS_IS_OK(result = r.status)) {
1210 *alias_pol = r.alias_pol;
1213 done:
1214 prs_mem_free(&qbuf);
1215 prs_mem_free(&rbuf);
1217 return result;
1220 /* Add an alias member */
1222 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1223 POLICY_HND *alias_pol, DOM_SID *member)
1225 prs_struct qbuf, rbuf;
1226 SAMR_Q_ADD_ALIASMEM q;
1227 SAMR_R_ADD_ALIASMEM r;
1228 NTSTATUS result;
1230 DEBUG(10,("cli_samr_add_aliasmem"));
1232 ZERO_STRUCT(q);
1233 ZERO_STRUCT(r);
1235 /* Initialise parse structures */
1237 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1238 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1240 /* Marshall data and send request */
1242 init_samr_q_add_aliasmem(&q, alias_pol, member);
1244 if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1245 !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1246 result = NT_STATUS_UNSUCCESSFUL;
1247 goto done;
1250 /* Unmarshall response */
1252 if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1253 result = NT_STATUS_UNSUCCESSFUL;
1254 goto done;
1257 result = r.status;
1259 done:
1260 prs_mem_free(&qbuf);
1261 prs_mem_free(&rbuf);
1263 return result;
1266 /* Delete an alias member */
1268 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1269 POLICY_HND *alias_pol, DOM_SID *member)
1271 prs_struct qbuf, rbuf;
1272 SAMR_Q_DEL_ALIASMEM q;
1273 SAMR_R_DEL_ALIASMEM r;
1274 NTSTATUS result;
1276 DEBUG(10,("cli_samr_del_aliasmem"));
1278 ZERO_STRUCT(q);
1279 ZERO_STRUCT(r);
1281 /* Initialise parse structures */
1283 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1284 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1286 /* Marshall data and send request */
1288 init_samr_q_del_aliasmem(&q, alias_pol, member);
1290 if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1291 !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1292 result = NT_STATUS_UNSUCCESSFUL;
1293 goto done;
1296 /* Unmarshall response */
1298 if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1299 result = NT_STATUS_UNSUCCESSFUL;
1300 goto done;
1303 result = r.status;
1305 done:
1306 prs_mem_free(&qbuf);
1307 prs_mem_free(&rbuf);
1309 return result;
1312 /* Query alias info */
1314 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1315 POLICY_HND *alias_pol, uint16 switch_value,
1316 ALIAS_INFO_CTR *ctr)
1318 prs_struct qbuf, rbuf;
1319 SAMR_Q_QUERY_ALIASINFO q;
1320 SAMR_R_QUERY_ALIASINFO r;
1321 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1323 DEBUG(10,("cli_samr_query_dom_info\n"));
1325 ZERO_STRUCT(q);
1326 ZERO_STRUCT(r);
1328 /* Initialise parse structures */
1330 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1331 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1333 /* Marshall data and send request */
1335 init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1337 if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1338 !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1339 goto done;
1342 /* Unmarshall response */
1344 if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1345 goto done;
1348 /* Return output parameters */
1350 if (!NT_STATUS_IS_OK(result = r.status)) {
1351 goto done;
1354 *ctr = r.ctr;
1356 done:
1357 prs_mem_free(&qbuf);
1358 prs_mem_free(&rbuf);
1360 return result;
1363 /* Query domain info */
1365 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1366 POLICY_HND *domain_pol, uint16 switch_value,
1367 SAM_UNK_CTR *ctr)
1369 prs_struct qbuf, rbuf;
1370 SAMR_Q_QUERY_DOMAIN_INFO q;
1371 SAMR_R_QUERY_DOMAIN_INFO r;
1372 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1374 DEBUG(10,("cli_samr_query_dom_info\n"));
1376 ZERO_STRUCT(q);
1377 ZERO_STRUCT(r);
1379 /* Initialise parse structures */
1381 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1382 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1384 /* Marshall data and send request */
1386 init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1388 if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1389 !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1390 goto done;
1393 /* Unmarshall response */
1395 r.ctr = ctr;
1397 if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1398 goto done;
1401 /* Return output parameters */
1403 if (!NT_STATUS_IS_OK(result = r.status)) {
1404 goto done;
1407 done:
1408 prs_mem_free(&qbuf);
1409 prs_mem_free(&rbuf);
1411 return result;
1414 /* User change password */
1416 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1417 const char *username,
1418 const char *newpassword,
1419 const char *oldpassword )
1421 prs_struct qbuf, rbuf;
1422 SAMR_Q_CHGPASSWD_USER q;
1423 SAMR_R_CHGPASSWD_USER r;
1424 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1426 uchar new_nt_password[516];
1427 uchar new_lm_password[516];
1428 uchar old_nt_hash[16];
1429 uchar old_lanman_hash[16];
1430 uchar old_nt_hash_enc[16];
1431 uchar old_lanman_hash_enc[16];
1433 uchar new_nt_hash[16];
1434 uchar new_lanman_hash[16];
1436 DEBUG(10,("cli_samr_query_dom_info\n"));
1438 ZERO_STRUCT(q);
1439 ZERO_STRUCT(r);
1441 /* Calculate the MD4 hash (NT compatible) of the password */
1442 E_md4hash(oldpassword, old_nt_hash);
1443 E_md4hash(newpassword, new_nt_hash);
1445 if (lp_client_lanman_auth()
1446 && E_deshash(newpassword, new_lanman_hash)
1447 && E_deshash(oldpassword, old_lanman_hash)) {
1448 /* E_deshash returns false for 'long' passwords (> 14
1449 DOS chars). This allows us to match Win2k, which
1450 does not store a LM hash for these passwords (which
1451 would reduce the effective password length to 14) */
1453 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1455 SamOEMhash( new_lm_password, old_nt_hash, 516);
1456 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1457 } else {
1458 ZERO_STRUCT(new_lm_password);
1459 ZERO_STRUCT(old_lanman_hash_enc);
1462 encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1464 SamOEMhash( new_nt_password, old_nt_hash, 516);
1465 E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1467 /* Initialise parse structures */
1469 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1470 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1472 /* Marshall data and send request */
1474 init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username,
1475 new_nt_password,
1476 old_nt_hash_enc,
1477 new_lm_password,
1478 old_lanman_hash_enc);
1480 if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1481 !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1482 goto done;
1485 /* Unmarshall response */
1487 if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1488 goto done;
1491 /* Return output parameters */
1493 if (!NT_STATUS_IS_OK(result = r.status)) {
1494 goto done;
1497 done:
1498 prs_mem_free(&qbuf);
1499 prs_mem_free(&rbuf);
1501 return result;
1504 /* This function returns the bizzare set of (max_entries, max_size) required
1505 for the QueryDisplayInfo RPC to actually work against a domain controller
1506 with large (10k and higher) numbers of users. These values were
1507 obtained by inspection using ethereal and NT4 running User Manager. */
1509 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1510 uint32 *max_size)
1512 switch(loop_count) {
1513 case 0:
1514 *max_entries = 512;
1515 *max_size = 16383;
1516 break;
1517 case 1:
1518 *max_entries = 1024;
1519 *max_size = 32766;
1520 break;
1521 case 2:
1522 *max_entries = 2048;
1523 *max_size = 65532;
1524 break;
1525 case 3:
1526 *max_entries = 4096;
1527 *max_size = 131064;
1528 break;
1529 default: /* loop_count >= 4 */
1530 *max_entries = 4096;
1531 *max_size = 131071;
1532 break;
1536 /* Query display info */
1538 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1539 POLICY_HND *domain_pol, uint32 *start_idx,
1540 uint16 switch_value, uint32 *num_entries,
1541 uint32 max_entries, uint32 max_size,
1542 SAM_DISPINFO_CTR *ctr)
1544 prs_struct qbuf, rbuf;
1545 SAMR_Q_QUERY_DISPINFO q;
1546 SAMR_R_QUERY_DISPINFO r;
1547 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1549 DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1551 ZERO_STRUCT(q);
1552 ZERO_STRUCT(r);
1554 *num_entries = 0;
1556 /* Initialise parse structures */
1558 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1559 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1561 /* Marshall data and send request */
1563 init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1564 *start_idx, max_entries, max_size);
1566 if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1567 !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1568 goto done;
1571 /* Unmarshall response */
1573 r.ctr = ctr;
1575 if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1576 goto done;
1579 /* Return output parameters */
1581 result = r.status;
1583 if (!NT_STATUS_IS_OK(result) &&
1584 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1585 goto done;
1588 *num_entries = r.num_entries;
1589 *start_idx += r.num_entries; /* No next_idx in this structure! */
1591 done:
1592 prs_mem_free(&qbuf);
1593 prs_mem_free(&rbuf);
1595 return result;
1598 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
1599 looked up in one packet. */
1601 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1602 POLICY_HND *domain_pol, uint32 flags,
1603 uint32 num_rids, uint32 *rids,
1604 uint32 *num_names, char ***names,
1605 uint32 **name_types)
1607 prs_struct qbuf, rbuf;
1608 SAMR_Q_LOOKUP_RIDS q;
1609 SAMR_R_LOOKUP_RIDS r;
1610 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1611 uint32 i;
1613 DEBUG(10,("cli_samr_lookup_rids\n"));
1615 if (num_rids > 1000) {
1616 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1617 "more than ~1000 rids are looked up at once.\n"));
1620 ZERO_STRUCT(q);
1621 ZERO_STRUCT(r);
1623 /* Initialise parse structures */
1625 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1626 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1628 /* Marshall data and send request */
1630 init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1631 num_rids, rids);
1633 if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1634 !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1635 goto done;
1638 /* Unmarshall response */
1640 if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1641 goto done;
1644 /* Return output parameters */
1646 if (!NT_STATUS_IS_OK(result = r.status)) {
1647 goto done;
1650 if (r.num_names1 == 0) {
1651 *num_names = 0;
1652 *names = NULL;
1653 goto done;
1656 *num_names = r.num_names1;
1657 *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
1658 *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
1660 for (i = 0; i < r.num_names1; i++) {
1661 fstring tmp;
1663 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1664 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1665 (*name_types)[i] = r.type[i];
1668 done:
1669 prs_mem_free(&qbuf);
1670 prs_mem_free(&rbuf);
1672 return result;
1675 /* Lookup names */
1677 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1678 POLICY_HND *domain_pol, uint32 flags,
1679 uint32 num_names, const char **names,
1680 uint32 *num_rids, uint32 **rids,
1681 uint32 **rid_types)
1683 prs_struct qbuf, rbuf;
1684 SAMR_Q_LOOKUP_NAMES q;
1685 SAMR_R_LOOKUP_NAMES r;
1686 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1687 uint32 i;
1689 DEBUG(10,("cli_samr_lookup_names\n"));
1691 ZERO_STRUCT(q);
1692 ZERO_STRUCT(r);
1694 /* Initialise parse structures */
1696 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1697 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1699 /* Marshall data and send request */
1701 init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1702 num_names, names);
1704 if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1705 !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1706 goto done;
1709 /* Unmarshall response */
1711 if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1712 goto done;
1715 /* Return output parameters */
1717 if (!NT_STATUS_IS_OK(result = r.status)) {
1718 goto done;
1721 if (r.num_rids1 == 0) {
1722 *num_rids = 0;
1723 goto done;
1726 *num_rids = r.num_rids1;
1727 *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1728 *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1730 for (i = 0; i < r.num_rids1; i++) {
1731 (*rids)[i] = r.rids[i];
1732 (*rid_types)[i] = r.types[i];
1735 done:
1736 prs_mem_free(&qbuf);
1737 prs_mem_free(&rbuf);
1739 return result;
1742 /* Create a domain user */
1744 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1745 POLICY_HND *domain_pol, const char *acct_name,
1746 uint32 acb_info, uint32 unknown,
1747 POLICY_HND *user_pol, uint32 *rid)
1749 prs_struct qbuf, rbuf;
1750 SAMR_Q_CREATE_USER q;
1751 SAMR_R_CREATE_USER r;
1752 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1754 DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1756 ZERO_STRUCT(q);
1757 ZERO_STRUCT(r);
1759 /* Initialise parse structures */
1761 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1762 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1764 /* Marshall data and send request */
1766 init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1768 if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1769 !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1770 goto done;
1773 /* Unmarshall response */
1775 if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1776 goto done;
1779 /* Return output parameters */
1781 if (!NT_STATUS_IS_OK(result = r.status)) {
1782 goto done;
1785 if (user_pol)
1786 *user_pol = r.user_pol;
1788 if (rid)
1789 *rid = r.user_rid;
1791 done:
1792 prs_mem_free(&qbuf);
1793 prs_mem_free(&rbuf);
1795 return result;
1798 /* Set userinfo */
1800 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1801 POLICY_HND *user_pol, uint16 switch_value,
1802 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1804 prs_struct qbuf, rbuf;
1805 SAMR_Q_SET_USERINFO q;
1806 SAMR_R_SET_USERINFO r;
1807 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1809 DEBUG(10,("cli_samr_set_userinfo\n"));
1811 ZERO_STRUCT(q);
1812 ZERO_STRUCT(r);
1814 if (!sess_key->length) {
1815 DEBUG(1, ("No user session key\n"));
1816 return NT_STATUS_NO_USER_SESSION_KEY;
1819 /* Initialise parse structures */
1821 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1822 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1824 /* Marshall data and send request */
1826 q.ctr = ctr;
1828 init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1829 ctr->info.id);
1831 if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1832 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1833 goto done;
1836 /* Unmarshall response */
1838 if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1839 goto done;
1842 /* Return output parameters */
1844 if (!NT_STATUS_IS_OK(result = r.status)) {
1845 goto done;
1848 done:
1849 prs_mem_free(&qbuf);
1850 prs_mem_free(&rbuf);
1852 return result;
1855 /* Set userinfo2 */
1857 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1858 POLICY_HND *user_pol, uint16 switch_value,
1859 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1861 prs_struct qbuf, rbuf;
1862 SAMR_Q_SET_USERINFO2 q;
1863 SAMR_R_SET_USERINFO2 r;
1864 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1866 DEBUG(10,("cli_samr_set_userinfo2\n"));
1868 if (!sess_key->length) {
1869 DEBUG(1, ("No user session key\n"));
1870 return NT_STATUS_NO_USER_SESSION_KEY;
1873 ZERO_STRUCT(q);
1874 ZERO_STRUCT(r);
1876 /* Initialise parse structures */
1878 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1879 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1881 /* Marshall data and send request */
1883 init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1885 if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1886 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1887 goto done;
1890 /* Unmarshall response */
1892 if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1893 goto done;
1896 /* Return output parameters */
1898 if (!NT_STATUS_IS_OK(result = r.status)) {
1899 goto done;
1902 done:
1903 prs_mem_free(&qbuf);
1904 prs_mem_free(&rbuf);
1906 return result;
1909 /* Delete domain user */
1911 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1912 POLICY_HND *user_pol)
1914 prs_struct qbuf, rbuf;
1915 SAMR_Q_DELETE_DOM_USER q;
1916 SAMR_R_DELETE_DOM_USER r;
1917 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1919 DEBUG(10,("cli_samr_delete_dom_user\n"));
1921 ZERO_STRUCT(q);
1922 ZERO_STRUCT(r);
1924 /* Initialise parse structures */
1926 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1927 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1929 /* Marshall data and send request */
1931 init_samr_q_delete_dom_user(&q, user_pol);
1933 if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1934 !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1935 goto done;
1938 /* Unmarshall response */
1940 if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1941 goto done;
1944 /* Return output parameters */
1946 result = r.status;
1948 done:
1949 prs_mem_free(&qbuf);
1950 prs_mem_free(&rbuf);
1952 return result;
1955 /* Query user security object */
1957 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1958 POLICY_HND *user_pol, uint16 switch_value,
1959 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1961 prs_struct qbuf, rbuf;
1962 SAMR_Q_QUERY_SEC_OBJ q;
1963 SAMR_R_QUERY_SEC_OBJ r;
1964 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1966 DEBUG(10,("cli_samr_query_sec_obj\n"));
1968 ZERO_STRUCT(q);
1969 ZERO_STRUCT(r);
1971 /* Initialise parse structures */
1973 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1974 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1976 /* Marshall data and send request */
1978 init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1980 if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1981 !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1982 goto done;
1985 /* Unmarshall response */
1987 if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1988 goto done;
1991 /* Return output parameters */
1993 result = r.status;
1994 *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1996 done:
1997 prs_mem_free(&qbuf);
1998 prs_mem_free(&rbuf);
2000 return result;
2003 /* Get domain password info */
2005 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2006 uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
2008 prs_struct qbuf, rbuf;
2009 SAMR_Q_GET_DOM_PWINFO q;
2010 SAMR_R_GET_DOM_PWINFO r;
2011 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2013 DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2015 ZERO_STRUCT(q);
2016 ZERO_STRUCT(r);
2018 /* Initialise parse structures */
2020 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2021 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2023 /* Marshall data and send request */
2025 init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2027 if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2028 !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2029 goto done;
2031 /* Unmarshall response */
2033 if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2034 goto done;
2036 /* Return output parameters */
2038 result = r.status;
2040 if (NT_STATUS_IS_OK(result)) {
2041 if (unk_0)
2042 *unk_0 = r.unk_0;
2043 if (unk_1)
2044 *unk_1 = r.unk_1;
2045 if (unk_2)
2046 *unk_2 = r.unk_2;
2049 done:
2050 prs_mem_free(&qbuf);
2051 prs_mem_free(&rbuf);
2053 return result;
2056 /* Lookup Domain Name */
2058 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2059 POLICY_HND *user_pol, char *domain_name,
2060 DOM_SID *sid)
2062 prs_struct qbuf, rbuf;
2063 SAMR_Q_LOOKUP_DOMAIN q;
2064 SAMR_R_LOOKUP_DOMAIN r;
2065 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2067 DEBUG(10,("cli_samr_lookup_domain\n"));
2069 ZERO_STRUCT(q);
2070 ZERO_STRUCT(r);
2072 /* Initialise parse structures */
2074 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2075 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2077 /* Marshall data and send request */
2079 init_samr_q_lookup_domain(&q, user_pol, domain_name);
2081 if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2082 !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2083 goto done;
2085 /* Unmarshall response */
2087 if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2088 goto done;
2090 /* Return output parameters */
2092 result = r.status;
2094 if (NT_STATUS_IS_OK(result))
2095 sid_copy(sid, &r.dom_sid.sid);
2097 done:
2098 prs_mem_free(&qbuf);
2099 prs_mem_free(&rbuf);
2101 return result;