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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
, 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
*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
;
703 DEBUG(10,("cli_samr_query_useraliases\n"));
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
))
721 /* Unmarshall response */
723 if (!samr_io_r_query_useraliases("", &r
, &rbuf
, 0))
726 /* Return output parameters */
728 if (NT_STATUS_IS_OK(result
= r
.status
)) {
729 *num_aliases
= r
.num_entries
;
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"));
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
))
769 /* Unmarshall response */
771 if (!samr_io_r_query_groupmem("", &r
, &rbuf
, 0))
774 /* Return output parameters */
776 if (NT_STATUS_IS_OK(result
= r
.status
)) {
777 *num_mem
= r
.num_entries
;
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
797 * @param acb_mask account control bit mask (to enumerate some particular
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
)
813 SAMR_Q_ENUM_DOM_USERS q
;
814 SAMR_R_ENUM_DOM_USERS r
;
815 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
818 DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx
));
823 /* always init this */
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
)) {
840 /* unpack received stream */
842 if(!samr_io_r_enum_dom_users("", &r
, &rbuf
, 0))
847 if (!NT_STATUS_IS_OK(result
) &&
848 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
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
);
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
);
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
++) {
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
);
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
;
898 DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx
));
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
))
916 /* Unmarshall response */
918 if (!samr_io_r_enum_dom_groups("", &r
, &rbuf
, 0))
921 /* Return output parameters */
925 if (!NT_STATUS_IS_OK(result
) &&
926 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
929 *num_dom_groups
= r
.num_entries2
;
931 if (*num_dom_groups
== 0)
934 if (!((*dom_groups
) = (struct acct_info
*)
935 talloc(mem_ctx
, sizeof(struct acct_info
) * *num_dom_groups
))) {
936 result
= NT_STATUS_NO_MEMORY
;
940 memset(*dom_groups
, 0, sizeof(struct acct_info
) * (*num_dom_groups
));
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);
955 *start_idx
= r
.next_idx
;
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
;
978 DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx
));
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
)) {
997 /* Unmarshall response */
999 if (!samr_io_r_enum_dom_aliases("", &r
, &rbuf
, 0)) {
1003 /* Return output parameters */
1007 if (!NT_STATUS_IS_OK(result
) &&
1008 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
1012 *num_dom_aliases
= r
.num_entries2
;
1014 if (*num_dom_aliases
== 0)
1017 if (!((*dom_aliases
) = (struct acct_info
*)
1018 talloc(mem_ctx
, sizeof(struct acct_info
) * *num_dom_aliases
))) {
1019 result
= NT_STATUS_NO_MEMORY
;
1023 memset(*dom_aliases
, 0, sizeof(struct acct_info
) * *num_dom_aliases
);
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);
1038 *start_idx
= r
.next_idx
;
1042 prs_mem_free(&qbuf
);
1043 prs_mem_free(&rbuf
);
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
,
1054 prs_struct qbuf
, rbuf
;
1055 SAMR_Q_QUERY_ALIASMEM q
;
1056 SAMR_R_QUERY_ALIASMEM r
;
1057 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1060 DEBUG(10,("cli_samr_query_aliasmem\n"));
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
)) {
1079 /* Unmarshall response */
1081 if (!samr_io_r_query_aliasmem("", &r
, &rbuf
, 0)) {
1085 /* Return output parameters */
1087 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1091 *num_mem
= r
.num_sids
;
1093 if (*num_mem
== 0) {
1095 result
= NT_STATUS_OK
;
1099 if (!(*sids
= talloc(mem_ctx
, sizeof(DOM_SID
) * *num_mem
))) {
1100 result
= NT_STATUS_UNSUCCESSFUL
;
1104 for (i
= 0; i
< *num_mem
; i
++) {
1105 (*sids
)[i
] = r
.sid
[i
].sid
;
1109 prs_mem_free(&qbuf
);
1110 prs_mem_free(&rbuf
);
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
;
1126 DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid
));
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
;
1146 /* Unmarshall response */
1148 if (!samr_io_r_open_alias("", &r
, &rbuf
, 0)) {
1149 result
= NT_STATUS_UNSUCCESSFUL
;
1153 /* Return output parameters */
1155 if (NT_STATUS_IS_OK(result
= r
.status
)) {
1158 alias_pol
->marker
= malloc(1);
1163 prs_mem_free(&qbuf
);
1164 prs_mem_free(&rbuf
);
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
;
1180 DEBUG(10,("cli_samr_create_dom_alias named %s\n", name
));
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
;
1200 /* Unmarshall response */
1202 if (!samr_io_r_create_dom_alias("", &r
, &rbuf
, 0)) {
1203 result
= NT_STATUS_UNSUCCESSFUL
;
1207 /* Return output parameters */
1209 if (NT_STATUS_IS_OK(result
= r
.status
)) {
1210 *alias_pol
= r
.alias_pol
;
1214 prs_mem_free(&qbuf
);
1215 prs_mem_free(&rbuf
);
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
;
1230 DEBUG(10,("cli_samr_add_aliasmem"));
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
;
1250 /* Unmarshall response */
1252 if (!samr_io_r_add_aliasmem("", &r
, &rbuf
, 0)) {
1253 result
= NT_STATUS_UNSUCCESSFUL
;
1260 prs_mem_free(&qbuf
);
1261 prs_mem_free(&rbuf
);
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
;
1276 DEBUG(10,("cli_samr_del_aliasmem"));
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
;
1296 /* Unmarshall response */
1298 if (!samr_io_r_del_aliasmem("", &r
, &rbuf
, 0)) {
1299 result
= NT_STATUS_UNSUCCESSFUL
;
1306 prs_mem_free(&qbuf
);
1307 prs_mem_free(&rbuf
);
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"));
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
)) {
1342 /* Unmarshall response */
1344 if (!samr_io_r_query_aliasinfo("", &r
, &rbuf
, 0)) {
1348 /* Return output parameters */
1350 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1357 prs_mem_free(&qbuf
);
1358 prs_mem_free(&rbuf
);
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
,
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"));
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
)) {
1393 /* Unmarshall response */
1397 if (!samr_io_r_query_dom_info("", &r
, &rbuf
, 0)) {
1401 /* Return output parameters */
1403 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1408 prs_mem_free(&qbuf
);
1409 prs_mem_free(&rbuf
);
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"));
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
);
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
,
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
)) {
1485 /* Unmarshall response */
1487 if (!samr_io_r_chgpasswd_user("", &r
, &rbuf
, 0)) {
1491 /* Return output parameters */
1493 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1498 prs_mem_free(&qbuf
);
1499 prs_mem_free(&rbuf
);
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
,
1512 switch(loop_count
) {
1518 *max_entries
= 1024;
1522 *max_entries
= 2048;
1526 *max_entries
= 4096;
1529 default: /* loop_count >= 4 */
1530 *max_entries
= 4096;
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
));
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
)) {
1571 /* Unmarshall response */
1575 if (!samr_io_r_query_dispinfo("", &r
, &rbuf
, 0)) {
1579 /* Return output parameters */
1583 if (!NT_STATUS_IS_OK(result
) &&
1584 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
1588 *num_entries
= r
.num_entries
;
1589 *start_idx
+= r
.num_entries
; /* No next_idx in this structure! */
1592 prs_mem_free(&qbuf
);
1593 prs_mem_free(&rbuf
);
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
;
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"));
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
,
1633 if (!samr_io_q_lookup_rids("", &q
, &qbuf
, 0) ||
1634 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_RIDS
, &qbuf
, &rbuf
)) {
1638 /* Unmarshall response */
1640 if (!samr_io_r_lookup_rids("", &r
, &rbuf
, 0)) {
1644 /* Return output parameters */
1646 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1650 if (r
.num_names1
== 0) {
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
++) {
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
];
1669 prs_mem_free(&qbuf
);
1670 prs_mem_free(&rbuf
);
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
,
1683 prs_struct qbuf
, rbuf
;
1684 SAMR_Q_LOOKUP_NAMES q
;
1685 SAMR_R_LOOKUP_NAMES r
;
1686 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1689 DEBUG(10,("cli_samr_lookup_names\n"));
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
,
1704 if (!samr_io_q_lookup_names("", &q
, &qbuf
, 0) ||
1705 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_NAMES
, &qbuf
, &rbuf
)) {
1709 /* Unmarshall response */
1711 if (!samr_io_r_lookup_names("", &r
, &rbuf
, 0)) {
1715 /* Return output parameters */
1717 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1721 if (r
.num_rids1
== 0) {
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
];
1736 prs_mem_free(&qbuf
);
1737 prs_mem_free(&rbuf
);
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
));
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
)) {
1773 /* Unmarshall response */
1775 if (!samr_io_r_create_user("", &r
, &rbuf
, 0)) {
1779 /* Return output parameters */
1781 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1786 *user_pol
= r
.user_pol
;
1792 prs_mem_free(&qbuf
);
1793 prs_mem_free(&rbuf
);
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"));
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 */
1828 init_samr_q_set_userinfo(&q
, user_pol
, sess_key
, switch_value
,
1831 if (!samr_io_q_set_userinfo("", &q
, &qbuf
, 0) ||
1832 !rpc_api_pipe_req(cli
, SAMR_SET_USERINFO
, &qbuf
, &rbuf
)) {
1836 /* Unmarshall response */
1838 if (!samr_io_r_set_userinfo("", &r
, &rbuf
, 0)) {
1842 /* Return output parameters */
1844 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1849 prs_mem_free(&qbuf
);
1850 prs_mem_free(&rbuf
);
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
;
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
)) {
1890 /* Unmarshall response */
1892 if (!samr_io_r_set_userinfo2("", &r
, &rbuf
, 0)) {
1896 /* Return output parameters */
1898 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1903 prs_mem_free(&qbuf
);
1904 prs_mem_free(&rbuf
);
1909 /* Delete domain group */
1911 NTSTATUS
cli_samr_delete_dom_group(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1912 POLICY_HND
*group_pol
)
1914 prs_struct qbuf
, rbuf
;
1915 SAMR_Q_DELETE_DOM_GROUP q
;
1916 SAMR_R_DELETE_DOM_GROUP r
;
1917 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1919 DEBUG(10,("cli_samr_delete_dom_group\n"));
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_group(&q
, group_pol
);
1933 if (!samr_io_q_delete_dom_group("", &q
, &qbuf
, 0) ||
1934 !rpc_api_pipe_req(cli
, SAMR_DELETE_DOM_GROUP
, &qbuf
, &rbuf
)) {
1938 /* Unmarshall response */
1940 if (!samr_io_r_delete_dom_group("", &r
, &rbuf
, 0)) {
1944 /* Return output parameters */
1949 prs_mem_free(&qbuf
);
1950 prs_mem_free(&rbuf
);
1955 /* Delete domain alias */
1957 NTSTATUS
cli_samr_delete_dom_alias(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1958 POLICY_HND
*alias_pol
)
1960 prs_struct qbuf
, rbuf
;
1961 SAMR_Q_DELETE_DOM_ALIAS q
;
1962 SAMR_R_DELETE_DOM_ALIAS r
;
1963 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1965 DEBUG(10,("cli_samr_delete_dom_alias\n"));
1970 /* Initialise parse structures */
1972 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1973 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1975 /* Marshall data and send request */
1977 init_samr_q_delete_dom_alias(&q
, alias_pol
);
1979 if (!samr_io_q_delete_dom_alias("", &q
, &qbuf
, 0) ||
1980 !rpc_api_pipe_req(cli
, SAMR_DELETE_DOM_ALIAS
, &qbuf
, &rbuf
)) {
1984 /* Unmarshall response */
1986 if (!samr_io_r_delete_dom_alias("", &r
, &rbuf
, 0)) {
1990 /* Return output parameters */
1995 prs_mem_free(&qbuf
);
1996 prs_mem_free(&rbuf
);
2001 /* Delete domain user */
2003 NTSTATUS
cli_samr_delete_dom_user(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
2004 POLICY_HND
*user_pol
)
2006 prs_struct qbuf
, rbuf
;
2007 SAMR_Q_DELETE_DOM_USER q
;
2008 SAMR_R_DELETE_DOM_USER r
;
2009 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2011 DEBUG(10,("cli_samr_delete_dom_user\n"));
2016 /* Initialise parse structures */
2018 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
2019 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
2021 /* Marshall data and send request */
2023 init_samr_q_delete_dom_user(&q
, user_pol
);
2025 if (!samr_io_q_delete_dom_user("", &q
, &qbuf
, 0) ||
2026 !rpc_api_pipe_req(cli
, SAMR_DELETE_DOM_USER
, &qbuf
, &rbuf
)) {
2030 /* Unmarshall response */
2032 if (!samr_io_r_delete_dom_user("", &r
, &rbuf
, 0)) {
2036 /* Return output parameters */
2041 prs_mem_free(&qbuf
);
2042 prs_mem_free(&rbuf
);
2047 /* Query user security object */
2049 NTSTATUS
cli_samr_query_sec_obj(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
2050 POLICY_HND
*user_pol
, uint16 switch_value
,
2051 TALLOC_CTX
*ctx
, SEC_DESC_BUF
**sec_desc_buf
)
2053 prs_struct qbuf
, rbuf
;
2054 SAMR_Q_QUERY_SEC_OBJ q
;
2055 SAMR_R_QUERY_SEC_OBJ r
;
2056 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2058 DEBUG(10,("cli_samr_query_sec_obj\n"));
2063 /* Initialise parse structures */
2065 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
2066 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
2068 /* Marshall data and send request */
2070 init_samr_q_query_sec_obj(&q
, user_pol
, switch_value
);
2072 if (!samr_io_q_query_sec_obj("", &q
, &qbuf
, 0) ||
2073 !rpc_api_pipe_req(cli
, SAMR_QUERY_SEC_OBJECT
, &qbuf
, &rbuf
)) {
2077 /* Unmarshall response */
2079 if (!samr_io_r_query_sec_obj("", &r
, &rbuf
, 0)) {
2083 /* Return output parameters */
2086 *sec_desc_buf
=dup_sec_desc_buf(ctx
, r
.buf
);
2089 prs_mem_free(&qbuf
);
2090 prs_mem_free(&rbuf
);
2095 /* Get domain password info */
2097 NTSTATUS
cli_samr_get_dom_pwinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
2098 uint16
*unk_0
, uint16
*unk_1
)
2100 prs_struct qbuf
, rbuf
;
2101 SAMR_Q_GET_DOM_PWINFO q
;
2102 SAMR_R_GET_DOM_PWINFO r
;
2103 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2105 DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2110 /* Initialise parse structures */
2112 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
2113 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
2115 /* Marshall data and send request */
2117 init_samr_q_get_dom_pwinfo(&q
, cli
->desthost
);
2119 if (!samr_io_q_get_dom_pwinfo("", &q
, &qbuf
, 0) ||
2120 !rpc_api_pipe_req(cli
, SAMR_GET_DOM_PWINFO
, &qbuf
, &rbuf
))
2123 /* Unmarshall response */
2125 if (!samr_io_r_get_dom_pwinfo("", &r
, &rbuf
, 0))
2128 /* Return output parameters */
2132 if (NT_STATUS_IS_OK(result
)) {
2140 prs_mem_free(&qbuf
);
2141 prs_mem_free(&rbuf
);
2146 /* Lookup Domain Name */
2148 NTSTATUS
cli_samr_lookup_domain(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
2149 POLICY_HND
*user_pol
, char *domain_name
,
2152 prs_struct qbuf
, rbuf
;
2153 SAMR_Q_LOOKUP_DOMAIN q
;
2154 SAMR_R_LOOKUP_DOMAIN r
;
2155 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2157 DEBUG(10,("cli_samr_lookup_domain\n"));
2162 /* Initialise parse structures */
2164 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
2165 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
2167 /* Marshall data and send request */
2169 init_samr_q_lookup_domain(&q
, user_pol
, domain_name
);
2171 if (!samr_io_q_lookup_domain("", &q
, &qbuf
, 0) ||
2172 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_DOMAIN
, &qbuf
, &rbuf
))
2175 /* Unmarshall response */
2177 if (!samr_io_r_lookup_domain("", &r
, &rbuf
, 0))
2180 /* Return output parameters */
2184 if (NT_STATUS_IS_OK(result
))
2185 sid_copy(sid
, &r
.dom_sid
.sid
);
2188 prs_mem_free(&qbuf
);
2189 prs_mem_free(&rbuf
);