2 Unix SMB/CIFS implementation.
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.
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;
36 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
38 DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
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, PI_SAMR, SAMR_CONNECT, &qbuf, &rbuf))
56 /* Unmarshall response */
58 if (!samr_io_r_connect("", &r, &rbuf, 0))
61 /* Return output parameters */
63 if (NT_STATUS_IS_OK(result = r.status)) {
64 *connect_pol = r.connect_pol;
66 connect_pol->marker = malloc(1);
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;
85 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
87 DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
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, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
105 /* Unmarshall response */
107 if (!samr_io_r_connect4("", &r, &rbuf, 0))
110 /* Return output parameters */
112 if (NT_STATUS_IS_OK(result = r.status)) {
113 *connect_pol = r.connect_pol;
115 connect_pol->marker = malloc(1);
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;
134 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
136 DEBUG(10,("cli_samr_close\n"));
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, PI_SAMR, SAMR_CLOSE_HND, &qbuf, &rbuf))
154 /* Unmarshall response */
156 if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
159 /* Return output parameters */
161 if (NT_STATUS_IS_OK(result = r.status)) {
163 SAFE_FREE(connect_pol->marker);
165 *connect_pol = r.pol;
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) ));
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, PI_SAMR, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
204 /* Unmarshall response */
206 if (!samr_io_r_open_domain("", &r, &rbuf, 0))
209 /* Return output parameters */
211 if (NT_STATUS_IS_OK(result = r.status)) {
212 *domain_pol = r.domain_pol;
214 domain_pol->marker = malloc(1);
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;
234 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
236 DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
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, PI_SAMR, SAMR_OPEN_USER, &qbuf, &rbuf))
254 /* Unmarshall response */
256 if (!samr_io_r_open_user("", &r, &rbuf, 0))
259 /* Return output parameters */
261 if (NT_STATUS_IS_OK(result = r.status)) {
262 *user_pol = r.user_pol;
264 user_pol->marker = malloc(1);
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;
284 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
286 DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
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, PI_SAMR, SAMR_OPEN_GROUP, &qbuf, &rbuf))
304 /* Unmarshall response */
306 if (!samr_io_r_open_group("", &r, &rbuf, 0))
309 /* Return output parameters */
311 if (NT_STATUS_IS_OK(result = r.status)) {
314 group_pol->marker = malloc(1);
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"));
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, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
355 /* Unmarshall response */
357 if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
360 /* Return output parameters */
364 if (NT_STATUS_IS_OK(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"));
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, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
402 /* Unmarshall response */
404 if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
407 /* Return output parameters */
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"));
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, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
446 /* Unmarshall response */
448 if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
451 /* Return output parameters */
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"));
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, PI_SAMR, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
491 /* Unmarshall response */
493 if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
496 /* Return output parameters */
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"));
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, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
536 /* Unmarshall response */
538 if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
541 /* Return output parameters */
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"));
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, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
581 /* Unmarshall response */
583 if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
588 /* Return output parameters */
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,
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"));
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, PI_SAMR, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
628 /* Unmarshall response */
630 if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
633 /* Return output parameters */
635 if (NT_STATUS_IS_OK(result = r.status)) {
636 *num_groups = r.num_entries;
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"));
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, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
675 /* Unmarshall response */
677 if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
680 /* Return output parameters */
691 /* Query user aliases */
693 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
694 POLICY_HND *dom_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;
704 DEBUG(10,("cli_samr_query_useraliases\n"));
709 /* Initialise parse structures */
711 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
712 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
714 sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
715 if (sid_ptrs == NULL)
716 return NT_STATUS_NO_MEMORY;
718 for (i=0; i<num_sids; i++)
721 /* Marshall data and send request */
723 init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
725 if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
726 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
729 /* Unmarshall response */
731 if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
734 /* Return output parameters */
736 if (NT_STATUS_IS_OK(result = r.status)) {
737 *num_aliases = r.num_entries;
748 /* Query user groups */
750 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
751 POLICY_HND *group_pol, uint32 *num_mem,
752 uint32 **rid, uint32 **attr)
754 prs_struct qbuf, rbuf;
755 SAMR_Q_QUERY_GROUPMEM q;
756 SAMR_R_QUERY_GROUPMEM r;
757 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
759 DEBUG(10,("cli_samr_query_groupmem\n"));
764 /* Initialise parse structures */
766 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
767 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
769 /* Marshall data and send request */
771 init_samr_q_query_groupmem(&q, group_pol);
773 if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
774 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
777 /* Unmarshall response */
779 if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
782 /* Return output parameters */
784 if (NT_STATUS_IS_OK(result = r.status)) {
785 *num_mem = r.num_entries;
798 * Enumerate domain users
800 * @param cli client state structure
801 * @param mem_ctx talloc context
802 * @param pol opened domain policy handle
803 * @param start_idx starting index of enumeration, returns context for
805 * @param acb_mask account control bit mask (to enumerate some particular
807 * @param size max acceptable size of response
808 * @param dom_users returned array of domain user names
809 * @param rids returned array of domain user RIDs
810 * @param num_dom_users numer returned entries
812 * @return NTSTATUS returned in rpc response
814 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
815 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
816 uint32 size, char ***dom_users, uint32 **rids,
817 uint32 *num_dom_users)
821 SAMR_Q_ENUM_DOM_USERS q;
822 SAMR_R_ENUM_DOM_USERS r;
823 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
826 DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
831 /* always init this */
834 /* Initialise parse structures */
836 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
837 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
839 /* Fill query structure with parameters */
841 init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
843 if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
844 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
848 /* unpack received stream */
850 if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
855 if (!NT_STATUS_IS_OK(result) &&
856 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
859 *start_idx = r.next_idx;
860 *num_dom_users = r.num_entries2;
862 if (r.num_entries2) {
863 /* allocate memory needed to return received data */
864 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
866 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
867 return NT_STATUS_NO_MEMORY;
870 *dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
872 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
873 return NT_STATUS_NO_MEMORY;
876 /* fill output buffers with rpc response */
877 for (i = 0; i < r.num_entries2; i++) {
880 (*rids)[i] = r.sam[i].rid;
881 unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
882 (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
893 /* Enumerate domain groups */
895 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
896 POLICY_HND *pol, uint32 *start_idx,
897 uint32 size, struct acct_info **dom_groups,
898 uint32 *num_dom_groups)
900 prs_struct qbuf, rbuf;
901 SAMR_Q_ENUM_DOM_GROUPS q;
902 SAMR_R_ENUM_DOM_GROUPS r;
903 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
906 DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
911 /* Initialise parse structures */
913 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
914 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
916 /* Marshall data and send request */
918 init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
920 if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
921 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
924 /* Unmarshall response */
926 if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
929 /* Return output parameters */
933 if (!NT_STATUS_IS_OK(result) &&
934 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
937 *num_dom_groups = r.num_entries2;
939 if (*num_dom_groups == 0)
942 if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
943 result = NT_STATUS_NO_MEMORY;
947 memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
951 for (i = 0; i < *num_dom_groups; i++) {
953 (*dom_groups)[i].rid = r.sam[i].rid;
955 if (r.sam[i].hdr_name.buffer) {
956 unistr2_to_ascii((*dom_groups)[i].acct_name,
957 &r.uni_grp_name[name_idx],
958 sizeof(fstring) - 1);
962 *start_idx = r.next_idx;
972 /* Enumerate domain groups */
974 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
975 POLICY_HND *pol, uint32 *start_idx,
976 uint32 size, struct acct_info **dom_aliases,
977 uint32 *num_dom_aliases)
979 prs_struct qbuf, rbuf;
980 SAMR_Q_ENUM_DOM_ALIASES q;
981 SAMR_R_ENUM_DOM_ALIASES r;
982 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
985 DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
990 /* Initialise parse structures */
992 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
993 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
995 /* Marshall data and send request */
997 init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
999 if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
1000 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
1004 /* Unmarshall response */
1006 if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1010 /* Return output parameters */
1014 if (!NT_STATUS_IS_OK(result) &&
1015 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1019 *num_dom_aliases = r.num_entries2;
1021 if (*num_dom_aliases == 0)
1024 if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
1025 result = NT_STATUS_NO_MEMORY;
1029 memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1033 for (i = 0; i < *num_dom_aliases; i++) {
1035 (*dom_aliases)[i].rid = r.sam[i].rid;
1037 if (r.sam[i].hdr_name.buffer) {
1038 unistr2_to_ascii((*dom_aliases)[i].acct_name,
1039 &r.uni_grp_name[name_idx],
1040 sizeof(fstring) - 1);
1044 *start_idx = r.next_idx;
1048 prs_mem_free(&qbuf);
1049 prs_mem_free(&rbuf);
1054 /* Query alias members */
1056 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1057 POLICY_HND *alias_pol, uint32 *num_mem,
1060 prs_struct qbuf, rbuf;
1061 SAMR_Q_QUERY_ALIASMEM q;
1062 SAMR_R_QUERY_ALIASMEM r;
1063 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1066 DEBUG(10,("cli_samr_query_aliasmem\n"));
1071 /* Initialise parse structures */
1073 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1074 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1076 /* Marshall data and send request */
1078 init_samr_q_query_aliasmem(&q, alias_pol);
1080 if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1081 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1085 /* Unmarshall response */
1087 if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1091 /* Return output parameters */
1093 if (!NT_STATUS_IS_OK(result = r.status)) {
1097 *num_mem = r.num_sids;
1099 if (*num_mem == 0) {
1101 result = NT_STATUS_OK;
1105 if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
1106 result = NT_STATUS_UNSUCCESSFUL;
1110 for (i = 0; i < *num_mem; i++) {
1111 (*sids)[i] = r.sid[i].sid;
1115 prs_mem_free(&qbuf);
1116 prs_mem_free(&rbuf);
1121 /* Open handle on an alias */
1123 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1124 POLICY_HND *domain_pol, uint32 access_mask,
1125 uint32 alias_rid, POLICY_HND *alias_pol)
1127 prs_struct qbuf, rbuf;
1128 SAMR_Q_OPEN_ALIAS q;
1129 SAMR_R_OPEN_ALIAS r;
1132 DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1137 /* Initialise parse structures */
1139 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1140 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1142 /* Marshall data and send request */
1144 init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1146 if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1147 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1148 result = NT_STATUS_UNSUCCESSFUL;
1152 /* Unmarshall response */
1154 if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1155 result = NT_STATUS_UNSUCCESSFUL;
1159 /* Return output parameters */
1161 if (NT_STATUS_IS_OK(result = r.status)) {
1164 alias_pol->marker = malloc(1);
1169 prs_mem_free(&qbuf);
1170 prs_mem_free(&rbuf);
1175 /* Create an alias */
1177 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1178 POLICY_HND *domain_pol, const char *name,
1179 POLICY_HND *alias_pol)
1181 prs_struct qbuf, rbuf;
1182 SAMR_Q_CREATE_DOM_ALIAS q;
1183 SAMR_R_CREATE_DOM_ALIAS r;
1186 DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1191 /* Initialise parse structures */
1193 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1194 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1196 /* Marshall data and send request */
1198 init_samr_q_create_dom_alias(&q, domain_pol, name);
1200 if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1201 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1202 result = NT_STATUS_UNSUCCESSFUL;
1206 /* Unmarshall response */
1208 if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1209 result = NT_STATUS_UNSUCCESSFUL;
1213 /* Return output parameters */
1215 if (NT_STATUS_IS_OK(result = r.status)) {
1216 *alias_pol = r.alias_pol;
1220 prs_mem_free(&qbuf);
1221 prs_mem_free(&rbuf);
1226 /* Add an alias member */
1228 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1229 POLICY_HND *alias_pol, DOM_SID *member)
1231 prs_struct qbuf, rbuf;
1232 SAMR_Q_ADD_ALIASMEM q;
1233 SAMR_R_ADD_ALIASMEM r;
1236 DEBUG(10,("cli_samr_add_aliasmem"));
1241 /* Initialise parse structures */
1243 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1244 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1246 /* Marshall data and send request */
1248 init_samr_q_add_aliasmem(&q, alias_pol, member);
1250 if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1251 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1252 result = NT_STATUS_UNSUCCESSFUL;
1256 /* Unmarshall response */
1258 if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1259 result = NT_STATUS_UNSUCCESSFUL;
1266 prs_mem_free(&qbuf);
1267 prs_mem_free(&rbuf);
1272 /* Delete an alias member */
1274 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1275 POLICY_HND *alias_pol, DOM_SID *member)
1277 prs_struct qbuf, rbuf;
1278 SAMR_Q_DEL_ALIASMEM q;
1279 SAMR_R_DEL_ALIASMEM r;
1282 DEBUG(10,("cli_samr_del_aliasmem"));
1287 /* Initialise parse structures */
1289 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1290 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1292 /* Marshall data and send request */
1294 init_samr_q_del_aliasmem(&q, alias_pol, member);
1296 if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1297 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1298 result = NT_STATUS_UNSUCCESSFUL;
1302 /* Unmarshall response */
1304 if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1305 result = NT_STATUS_UNSUCCESSFUL;
1312 prs_mem_free(&qbuf);
1313 prs_mem_free(&rbuf);
1318 /* Query alias info */
1320 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1321 POLICY_HND *alias_pol, uint16 switch_value,
1322 ALIAS_INFO_CTR *ctr)
1324 prs_struct qbuf, rbuf;
1325 SAMR_Q_QUERY_ALIASINFO q;
1326 SAMR_R_QUERY_ALIASINFO r;
1327 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1329 DEBUG(10,("cli_samr_query_dom_info\n"));
1334 /* Initialise parse structures */
1336 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1337 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1339 /* Marshall data and send request */
1341 init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1343 if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1344 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1348 /* Unmarshall response */
1350 if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1354 /* Return output parameters */
1356 if (!NT_STATUS_IS_OK(result = r.status)) {
1363 prs_mem_free(&qbuf);
1364 prs_mem_free(&rbuf);
1369 /* Query domain info */
1371 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1372 POLICY_HND *domain_pol, uint16 switch_value,
1375 prs_struct qbuf, rbuf;
1376 SAMR_Q_QUERY_DOMAIN_INFO q;
1377 SAMR_R_QUERY_DOMAIN_INFO r;
1378 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1380 DEBUG(10,("cli_samr_query_dom_info\n"));
1385 /* Initialise parse structures */
1387 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1388 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1390 /* Marshall data and send request */
1392 init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1394 if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1395 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1399 /* Unmarshall response */
1403 if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1407 /* Return output parameters */
1409 if (!NT_STATUS_IS_OK(result = r.status)) {
1414 prs_mem_free(&qbuf);
1415 prs_mem_free(&rbuf);
1420 /* User change password */
1422 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1423 const char *username,
1424 const char *newpassword,
1425 const char *oldpassword )
1427 prs_struct qbuf, rbuf;
1428 SAMR_Q_CHGPASSWD_USER q;
1429 SAMR_R_CHGPASSWD_USER r;
1430 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1432 uchar new_nt_password[516];
1433 uchar new_lm_password[516];
1434 uchar old_nt_hash[16];
1435 uchar old_lanman_hash[16];
1436 uchar old_nt_hash_enc[16];
1437 uchar old_lanman_hash_enc[16];
1439 uchar new_nt_hash[16];
1440 uchar new_lanman_hash[16];
1442 DEBUG(10,("cli_samr_query_dom_info\n"));
1447 /* Calculate the MD4 hash (NT compatible) of the password */
1448 E_md4hash(oldpassword, old_nt_hash);
1449 E_md4hash(newpassword, new_nt_hash);
1451 if (lp_client_lanman_auth()
1452 && E_deshash(newpassword, new_lanman_hash)
1453 && E_deshash(oldpassword, old_lanman_hash)) {
1454 /* E_deshash returns false for 'long' passwords (> 14
1455 DOS chars). This allows us to match Win2k, which
1456 does not store a LM hash for these passwords (which
1457 would reduce the effective password length to 14) */
1459 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1461 SamOEMhash( new_lm_password, old_nt_hash, 516);
1462 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1464 ZERO_STRUCT(new_lm_password);
1465 ZERO_STRUCT(old_lanman_hash_enc);
1468 encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1470 SamOEMhash( new_nt_password, old_nt_hash, 516);
1471 E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1473 /* Initialise parse structures */
1475 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1476 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1478 /* Marshall data and send request */
1480 init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username,
1484 old_lanman_hash_enc);
1486 if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1487 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1491 /* Unmarshall response */
1493 if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1497 /* Return output parameters */
1499 if (!NT_STATUS_IS_OK(result = r.status)) {
1504 prs_mem_free(&qbuf);
1505 prs_mem_free(&rbuf);
1510 /* This function returns the bizzare set of (max_entries, max_size) required
1511 for the QueryDisplayInfo RPC to actually work against a domain controller
1512 with large (10k and higher) numbers of users. These values were
1513 obtained by inspection using ethereal and NT4 running User Manager. */
1515 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1518 switch(loop_count) {
1524 *max_entries = 1024;
1528 *max_entries = 2048;
1532 *max_entries = 4096;
1535 default: /* loop_count >= 4 */
1536 *max_entries = 4096;
1542 /* Query display info */
1544 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1545 POLICY_HND *domain_pol, uint32 *start_idx,
1546 uint16 switch_value, uint32 *num_entries,
1547 uint32 max_entries, uint32 max_size,
1548 SAM_DISPINFO_CTR *ctr)
1550 prs_struct qbuf, rbuf;
1551 SAMR_Q_QUERY_DISPINFO q;
1552 SAMR_R_QUERY_DISPINFO r;
1553 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1555 DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1562 /* Initialise parse structures */
1564 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1565 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1567 /* Marshall data and send request */
1569 init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1570 *start_idx, max_entries, max_size);
1572 if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1573 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1577 /* Unmarshall response */
1581 if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1585 /* Return output parameters */
1589 if (!NT_STATUS_IS_OK(result) &&
1590 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1594 *num_entries = r.num_entries;
1595 *start_idx += r.num_entries; /* No next_idx in this structure! */
1598 prs_mem_free(&qbuf);
1599 prs_mem_free(&rbuf);
1604 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
1605 looked up in one packet. */
1607 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1608 POLICY_HND *domain_pol,
1609 uint32 num_rids, uint32 *rids,
1610 uint32 *num_names, char ***names,
1611 uint32 **name_types)
1613 prs_struct qbuf, rbuf;
1614 SAMR_Q_LOOKUP_RIDS q;
1615 SAMR_R_LOOKUP_RIDS r;
1616 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1619 DEBUG(10,("cli_samr_lookup_rids\n"));
1621 if (num_rids > 1000) {
1622 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1623 "more than ~1000 rids are looked up at once.\n"));
1629 /* Initialise parse structures */
1631 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1632 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1634 /* Marshall data and send request */
1636 init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
1638 if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1639 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1643 /* Unmarshall response */
1645 if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1649 /* Return output parameters */
1653 if (!NT_STATUS_IS_OK(result) &&
1654 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1657 if (r.num_names1 == 0) {
1663 *num_names = r.num_names1;
1664 *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1665 *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1667 for (i = 0; i < r.num_names1; i++) {
1670 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1671 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1672 (*name_types)[i] = r.type[i];
1676 prs_mem_free(&qbuf);
1677 prs_mem_free(&rbuf);
1684 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1685 POLICY_HND *domain_pol, uint32 flags,
1686 uint32 num_names, const char **names,
1687 uint32 *num_rids, uint32 **rids,
1690 prs_struct qbuf, rbuf;
1691 SAMR_Q_LOOKUP_NAMES q;
1692 SAMR_R_LOOKUP_NAMES r;
1693 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1696 DEBUG(10,("cli_samr_lookup_names\n"));
1701 /* Initialise parse structures */
1703 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1704 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1706 /* Marshall data and send request */
1708 init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1711 if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1712 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1716 /* Unmarshall response */
1718 if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1722 /* Return output parameters */
1724 if (!NT_STATUS_IS_OK(result = r.status)) {
1728 if (r.num_rids1 == 0) {
1733 *num_rids = r.num_rids1;
1734 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1735 *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1737 for (i = 0; i < r.num_rids1; i++) {
1738 (*rids)[i] = r.rids[i];
1739 (*rid_types)[i] = r.types[i];
1743 prs_mem_free(&qbuf);
1744 prs_mem_free(&rbuf);
1749 /* Create a domain user */
1751 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1752 POLICY_HND *domain_pol, const char *acct_name,
1753 uint32 acb_info, uint32 unknown,
1754 POLICY_HND *user_pol, uint32 *rid)
1756 prs_struct qbuf, rbuf;
1757 SAMR_Q_CREATE_USER q;
1758 SAMR_R_CREATE_USER r;
1759 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1761 DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1766 /* Initialise parse structures */
1768 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1769 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1771 /* Marshall data and send request */
1773 init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1775 if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1776 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1780 /* Unmarshall response */
1782 if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1786 /* Return output parameters */
1788 if (!NT_STATUS_IS_OK(result = r.status)) {
1793 *user_pol = r.user_pol;
1799 prs_mem_free(&qbuf);
1800 prs_mem_free(&rbuf);
1807 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1808 POLICY_HND *user_pol, uint16 switch_value,
1809 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1811 prs_struct qbuf, rbuf;
1812 SAMR_Q_SET_USERINFO q;
1813 SAMR_R_SET_USERINFO r;
1814 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1816 DEBUG(10,("cli_samr_set_userinfo\n"));
1821 if (!sess_key->length) {
1822 DEBUG(1, ("No user session key\n"));
1823 return NT_STATUS_NO_USER_SESSION_KEY;
1826 /* Initialise parse structures */
1828 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1829 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1831 /* Marshall data and send request */
1835 init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1838 if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1839 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1843 /* Unmarshall response */
1845 if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1849 /* Return output parameters */
1851 if (!NT_STATUS_IS_OK(result = r.status)) {
1856 prs_mem_free(&qbuf);
1857 prs_mem_free(&rbuf);
1864 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1865 POLICY_HND *user_pol, uint16 switch_value,
1866 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1868 prs_struct qbuf, rbuf;
1869 SAMR_Q_SET_USERINFO2 q;
1870 SAMR_R_SET_USERINFO2 r;
1871 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1873 DEBUG(10,("cli_samr_set_userinfo2\n"));
1875 if (!sess_key->length) {
1876 DEBUG(1, ("No user session key\n"));
1877 return NT_STATUS_NO_USER_SESSION_KEY;
1883 /* Initialise parse structures */
1885 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1886 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1888 /* Marshall data and send request */
1890 init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1892 if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1893 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1897 /* Unmarshall response */
1899 if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1903 /* Return output parameters */
1905 if (!NT_STATUS_IS_OK(result = r.status)) {
1910 prs_mem_free(&qbuf);
1911 prs_mem_free(&rbuf);
1916 /* Delete domain group */
1918 NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1919 POLICY_HND *group_pol)
1921 prs_struct qbuf, rbuf;
1922 SAMR_Q_DELETE_DOM_GROUP q;
1923 SAMR_R_DELETE_DOM_GROUP r;
1924 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1926 DEBUG(10,("cli_samr_delete_dom_group\n"));
1931 /* Initialise parse structures */
1933 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1934 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1936 /* Marshall data and send request */
1938 init_samr_q_delete_dom_group(&q, group_pol);
1940 if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
1941 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
1945 /* Unmarshall response */
1947 if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
1951 /* Return output parameters */
1956 prs_mem_free(&qbuf);
1957 prs_mem_free(&rbuf);
1962 /* Delete domain alias */
1964 NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1965 POLICY_HND *alias_pol)
1967 prs_struct qbuf, rbuf;
1968 SAMR_Q_DELETE_DOM_ALIAS q;
1969 SAMR_R_DELETE_DOM_ALIAS r;
1970 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1972 DEBUG(10,("cli_samr_delete_dom_alias\n"));
1977 /* Initialise parse structures */
1979 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1980 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1982 /* Marshall data and send request */
1984 init_samr_q_delete_dom_alias(&q, alias_pol);
1986 if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
1987 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
1991 /* Unmarshall response */
1993 if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
1997 /* Return output parameters */
2002 prs_mem_free(&qbuf);
2003 prs_mem_free(&rbuf);
2008 /* Delete domain user */
2010 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2011 POLICY_HND *user_pol)
2013 prs_struct qbuf, rbuf;
2014 SAMR_Q_DELETE_DOM_USER q;
2015 SAMR_R_DELETE_DOM_USER r;
2016 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2018 DEBUG(10,("cli_samr_delete_dom_user\n"));
2023 /* Initialise parse structures */
2025 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2026 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2028 /* Marshall data and send request */
2030 init_samr_q_delete_dom_user(&q, user_pol);
2032 if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
2033 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
2037 /* Unmarshall response */
2039 if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
2043 /* Return output parameters */
2048 prs_mem_free(&qbuf);
2049 prs_mem_free(&rbuf);
2054 /* Remove foreign SID */
2056 NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli,
2057 TALLOC_CTX *mem_ctx,
2058 POLICY_HND *user_pol,
2061 prs_struct qbuf, rbuf;
2062 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
2063 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
2064 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2066 DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
2071 /* Initialise parse structures */
2073 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2074 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2076 /* Marshall data and send request */
2078 init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
2080 if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
2081 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
2085 /* Unmarshall response */
2087 if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
2091 /* Return output parameters */
2096 prs_mem_free(&qbuf);
2097 prs_mem_free(&rbuf);
2102 /* Query user security object */
2104 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2105 POLICY_HND *user_pol, uint16 switch_value,
2106 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
2108 prs_struct qbuf, rbuf;
2109 SAMR_Q_QUERY_SEC_OBJ q;
2110 SAMR_R_QUERY_SEC_OBJ r;
2111 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2113 DEBUG(10,("cli_samr_query_sec_obj\n"));
2118 /* Initialise parse structures */
2120 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2121 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2123 /* Marshall data and send request */
2125 init_samr_q_query_sec_obj(&q, user_pol, switch_value);
2127 if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
2128 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
2132 /* Unmarshall response */
2134 if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
2138 /* Return output parameters */
2141 *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
2144 prs_mem_free(&qbuf);
2145 prs_mem_free(&rbuf);
2150 /* Get domain password info */
2152 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2153 uint16 *unk_0, uint16 *unk_1)
2155 prs_struct qbuf, rbuf;
2156 SAMR_Q_GET_DOM_PWINFO q;
2157 SAMR_R_GET_DOM_PWINFO r;
2158 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2160 DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2165 /* Initialise parse structures */
2167 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2168 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2170 /* Marshall data and send request */
2172 init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2174 if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2175 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2178 /* Unmarshall response */
2180 if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2183 /* Return output parameters */
2187 if (NT_STATUS_IS_OK(result)) {
2195 prs_mem_free(&qbuf);
2196 prs_mem_free(&rbuf);
2201 /* Lookup Domain Name */
2203 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2204 POLICY_HND *user_pol, char *domain_name,
2207 prs_struct qbuf, rbuf;
2208 SAMR_Q_LOOKUP_DOMAIN q;
2209 SAMR_R_LOOKUP_DOMAIN r;
2210 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2212 DEBUG(10,("cli_samr_lookup_domain\n"));
2217 /* Initialise parse structures */
2219 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2220 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2222 /* Marshall data and send request */
2224 init_samr_q_lookup_domain(&q, user_pol, domain_name);
2226 if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2227 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2230 /* Unmarshall response */
2232 if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2235 /* Return output parameters */
2239 if (NT_STATUS_IS_OK(result))
2240 sid_copy(sid, &r.dom_sid.sid);
2243 prs_mem_free(&qbuf);
2244 prs_mem_free(&rbuf);