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
;
41 /* Initialise parse structures */
43 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
44 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
46 /* Marshall data and send request */
48 init_samr_q_connect(&q
, cli
->desthost
, access_mask
);
50 if (!samr_io_q_connect("", &q
, &qbuf
, 0) ||
51 !rpc_api_pipe_req(cli
, SAMR_CONNECT
, &qbuf
, &rbuf
))
54 /* Unmarshall response */
56 if (!samr_io_r_connect("", &r
, &rbuf
, 0))
59 /* Return output parameters */
61 if (NT_STATUS_IS_OK(result
= r
.status
)) {
62 *connect_pol
= r
.connect_pol
;
64 connect_pol
->marker
= malloc(1);
75 /* Connect to SAMR database */
77 NTSTATUS
cli_samr_connect4(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
78 uint32 access_mask
, POLICY_HND
*connect_pol
)
80 prs_struct qbuf
, rbuf
;
83 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
88 /* Initialise parse structures */
90 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
91 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
93 /* Marshall data and send request */
95 init_samr_q_connect4(&q
, cli
->desthost
, access_mask
);
97 if (!samr_io_q_connect4("", &q
, &qbuf
, 0) ||
98 !rpc_api_pipe_req(cli
, SAMR_CONNECT4
, &qbuf
, &rbuf
))
101 /* Unmarshall response */
103 if (!samr_io_r_connect4("", &r
, &rbuf
, 0))
106 /* Return output parameters */
108 if (NT_STATUS_IS_OK(result
= r
.status
)) {
109 *connect_pol
= r
.connect_pol
;
111 connect_pol
->marker
= malloc(1);
122 /* Close SAMR handle */
124 NTSTATUS
cli_samr_close(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
125 POLICY_HND
*connect_pol
)
127 prs_struct qbuf
, rbuf
;
130 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
135 /* Initialise parse structures */
137 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
138 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
140 /* Marshall data and send request */
142 init_samr_q_close_hnd(&q
, connect_pol
);
144 if (!samr_io_q_close_hnd("", &q
, &qbuf
, 0) ||
145 !rpc_api_pipe_req(cli
, SAMR_CLOSE_HND
, &qbuf
, &rbuf
))
148 /* Unmarshall response */
150 if (!samr_io_r_close_hnd("", &r
, &rbuf
, 0))
153 /* Return output parameters */
155 if (NT_STATUS_IS_OK(result
= r
.status
)) {
157 SAFE_FREE(connect_pol
->marker
);
159 *connect_pol
= r
.pol
;
169 /* Open handle on a domain */
171 NTSTATUS
cli_samr_open_domain(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
172 POLICY_HND
*connect_pol
, uint32 access_mask
,
173 const DOM_SID
*domain_sid
, POLICY_HND
*domain_pol
)
175 prs_struct qbuf
, rbuf
;
176 SAMR_Q_OPEN_DOMAIN q
;
177 SAMR_R_OPEN_DOMAIN r
;
178 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
183 /* Initialise parse structures */
185 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
186 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
188 /* Marshall data and send request */
190 init_samr_q_open_domain(&q
, connect_pol
, access_mask
, domain_sid
);
192 if (!samr_io_q_open_domain("", &q
, &qbuf
, 0) ||
193 !rpc_api_pipe_req(cli
, SAMR_OPEN_DOMAIN
, &qbuf
, &rbuf
))
196 /* Unmarshall response */
198 if (!samr_io_r_open_domain("", &r
, &rbuf
, 0))
201 /* Return output parameters */
203 if (NT_STATUS_IS_OK(result
= r
.status
)) {
204 *domain_pol
= r
.domain_pol
;
206 domain_pol
->marker
= malloc(1);
217 /* Open handle on a user */
219 NTSTATUS
cli_samr_open_user(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
220 POLICY_HND
*domain_pol
, uint32 access_mask
,
221 uint32 user_rid
, POLICY_HND
*user_pol
)
223 prs_struct qbuf
, rbuf
;
226 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
231 /* Initialise parse structures */
233 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
234 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
236 /* Marshall data and send request */
238 init_samr_q_open_user(&q
, domain_pol
, access_mask
, user_rid
);
240 if (!samr_io_q_open_user("", &q
, &qbuf
, 0) ||
241 !rpc_api_pipe_req(cli
, SAMR_OPEN_USER
, &qbuf
, &rbuf
))
244 /* Unmarshall response */
246 if (!samr_io_r_open_user("", &r
, &rbuf
, 0))
249 /* Return output parameters */
251 if (NT_STATUS_IS_OK(result
= r
.status
)) {
252 *user_pol
= r
.user_pol
;
254 user_pol
->marker
= malloc(1);
265 /* Open handle on a group */
267 NTSTATUS
cli_samr_open_group(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
268 POLICY_HND
*domain_pol
, uint32 access_mask
,
269 uint32 group_rid
, POLICY_HND
*group_pol
)
271 prs_struct qbuf
, rbuf
;
274 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
279 /* Initialise parse structures */
281 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
282 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
284 /* Marshall data and send request */
286 init_samr_q_open_group(&q
, domain_pol
, access_mask
, group_rid
);
288 if (!samr_io_q_open_group("", &q
, &qbuf
, 0) ||
289 !rpc_api_pipe_req(cli
, SAMR_OPEN_GROUP
, &qbuf
, &rbuf
))
292 /* Unmarshall response */
294 if (!samr_io_r_open_group("", &r
, &rbuf
, 0))
297 /* Return output parameters */
299 if (NT_STATUS_IS_OK(result
= r
.status
)) {
302 group_pol
->marker
= malloc(1);
313 /* Query user info */
315 NTSTATUS
cli_samr_query_userinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
316 POLICY_HND
*user_pol
, uint16 switch_value
,
317 SAM_USERINFO_CTR
**ctr
)
319 prs_struct qbuf
, rbuf
;
320 SAMR_Q_QUERY_USERINFO q
;
321 SAMR_R_QUERY_USERINFO r
;
322 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
327 /* Initialise parse structures */
329 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
330 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
332 /* Marshall data and send request */
334 init_samr_q_query_userinfo(&q
, user_pol
, switch_value
);
336 if (!samr_io_q_query_userinfo("", &q
, &qbuf
, 0) ||
337 !rpc_api_pipe_req(cli
, SAMR_QUERY_USERINFO
, &qbuf
, &rbuf
))
340 /* Unmarshall response */
342 if (!samr_io_r_query_userinfo("", &r
, &rbuf
, 0))
345 /* Return output parameters */
357 /* Query group info */
359 NTSTATUS
cli_samr_query_groupinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
360 POLICY_HND
*group_pol
, uint32 info_level
,
361 GROUP_INFO_CTR
**ctr
)
363 prs_struct qbuf
, rbuf
;
364 SAMR_Q_QUERY_GROUPINFO q
;
365 SAMR_R_QUERY_GROUPINFO r
;
366 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
371 /* Initialise parse structures */
373 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
374 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
376 /* Marshall data and send request */
378 init_samr_q_query_groupinfo(&q
, group_pol
, info_level
);
380 if (!samr_io_q_query_groupinfo("", &q
, &qbuf
, 0) ||
381 !rpc_api_pipe_req(cli
, SAMR_QUERY_GROUPINFO
, &qbuf
, &rbuf
))
384 /* Unmarshall response */
386 if (!samr_io_r_query_groupinfo("", &r
, &rbuf
, 0))
391 /* Return output parameters */
402 /* Query user groups */
404 NTSTATUS
cli_samr_query_usergroups(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
405 POLICY_HND
*user_pol
, uint32
*num_groups
,
408 prs_struct qbuf
, rbuf
;
409 SAMR_Q_QUERY_USERGROUPS q
;
410 SAMR_R_QUERY_USERGROUPS r
;
411 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
416 /* Initialise parse structures */
418 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
419 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
421 /* Marshall data and send request */
423 init_samr_q_query_usergroups(&q
, user_pol
);
425 if (!samr_io_q_query_usergroups("", &q
, &qbuf
, 0) ||
426 !rpc_api_pipe_req(cli
, SAMR_QUERY_USERGROUPS
, &qbuf
, &rbuf
))
429 /* Unmarshall response */
431 if (!samr_io_r_query_usergroups("", &r
, &rbuf
, 0))
434 /* Return output parameters */
436 if (NT_STATUS_IS_OK(result
= r
.status
)) {
437 *num_groups
= r
.num_entries
;
448 /* Query user aliases */
450 NTSTATUS
cli_samr_query_useraliases(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
451 POLICY_HND
*user_pol
, uint32 num_sids
, DOM_SID2
*sid
,
452 uint32
*num_aliases
, uint32
**als_rids
)
454 prs_struct qbuf
, rbuf
;
455 SAMR_Q_QUERY_USERALIASES q
;
456 SAMR_R_QUERY_USERALIASES r
;
457 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
463 /* Initialise parse structures */
465 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
466 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
468 /* Marshall data and send request */
470 init_samr_q_query_useraliases(&q
, user_pol
, num_sids
, &ptr
, sid
);
472 if (!samr_io_q_query_useraliases("", &q
, &qbuf
, 0) ||
473 !rpc_api_pipe_req(cli
, SAMR_QUERY_USERALIASES
, &qbuf
, &rbuf
))
476 /* Unmarshall response */
478 if (!samr_io_r_query_useraliases("", &r
, &rbuf
, 0))
481 /* Return output parameters */
483 if (NT_STATUS_IS_OK(result
= r
.status
)) {
484 *num_aliases
= r
.num_entries
;
495 /* Query user groups */
497 NTSTATUS
cli_samr_query_groupmem(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
498 POLICY_HND
*group_pol
, uint32
*num_mem
,
499 uint32
**rid
, uint32
**attr
)
501 prs_struct qbuf
, rbuf
;
502 SAMR_Q_QUERY_GROUPMEM q
;
503 SAMR_R_QUERY_GROUPMEM r
;
504 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
509 /* Initialise parse structures */
511 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
512 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
514 /* Marshall data and send request */
516 init_samr_q_query_groupmem(&q
, group_pol
);
518 if (!samr_io_q_query_groupmem("", &q
, &qbuf
, 0) ||
519 !rpc_api_pipe_req(cli
, SAMR_QUERY_GROUPMEM
, &qbuf
, &rbuf
))
522 /* Unmarshall response */
524 if (!samr_io_r_query_groupmem("", &r
, &rbuf
, 0))
527 /* Return output parameters */
529 if (NT_STATUS_IS_OK(result
= r
.status
)) {
530 *num_mem
= r
.num_entries
;
543 * Enumerate domain users
545 * @param cli client state structure
546 * @param mem_ctx talloc context
547 * @param pol opened domain policy handle
548 * @param start_idx starting index of enumeration, returns context for
550 * @param acb_mask account control bit mask (to enumerate some particular
552 * @param size max acceptable size of response
553 * @param dom_users returned array of domain user names
554 * @param rids returned array of domain user RIDs
555 * @param num_dom_users numer returned entries
557 * @return NTSTATUS returned in rpc response
559 NTSTATUS
cli_samr_enum_dom_users(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
560 POLICY_HND
*pol
, uint32
*start_idx
, uint16 acb_mask
,
561 uint32 size
, char ***dom_users
, uint32
**rids
,
562 uint32
*num_dom_users
)
566 SAMR_Q_ENUM_DOM_USERS q
;
567 SAMR_R_ENUM_DOM_USERS r
;
568 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
574 /* always init this */
577 /* Initialise parse structures */
579 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
580 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
582 /* Fill query structure with parameters */
584 init_samr_q_enum_dom_users(&q
, pol
, *start_idx
, acb_mask
, 0, size
);
586 if (!samr_io_q_enum_dom_users("", &q
, &qbuf
, 0) ||
587 !rpc_api_pipe_req(cli
, SAMR_ENUM_DOM_USERS
, &qbuf
, &rbuf
)) {
591 /* unpack received stream */
593 if(!samr_io_r_enum_dom_users("", &r
, &rbuf
, 0))
598 if (!NT_STATUS_IS_OK(result
) &&
599 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
602 *start_idx
= r
.next_idx
;
603 *num_dom_users
= r
.num_entries2
;
605 if (r
.num_entries2
) {
606 /* allocate memory needed to return received data */
607 *rids
= (uint32
*)talloc(mem_ctx
, sizeof(uint32
) * r
.num_entries2
);
609 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
610 return NT_STATUS_NO_MEMORY
;
613 *dom_users
= (char**)talloc(mem_ctx
, sizeof(char*) * r
.num_entries2
);
615 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
616 return NT_STATUS_NO_MEMORY
;
619 /* fill output buffers with rpc response */
620 for (i
= 0; i
< r
.num_entries2
; i
++) {
623 (*rids
)[i
] = r
.sam
[i
].rid
;
624 unistr2_to_ascii(conv_buf
, &(r
.uni_acct_name
[i
]), sizeof(conv_buf
) - 1);
625 (*dom_users
)[i
] = talloc_strdup(mem_ctx
, conv_buf
);
636 /* Enumerate domain groups */
638 NTSTATUS
cli_samr_enum_dom_groups(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
639 POLICY_HND
*pol
, uint32
*start_idx
,
640 uint32 size
, struct acct_info
**dom_groups
,
641 uint32
*num_dom_groups
)
643 prs_struct qbuf
, rbuf
;
644 SAMR_Q_ENUM_DOM_GROUPS q
;
645 SAMR_R_ENUM_DOM_GROUPS r
;
646 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
652 /* Initialise parse structures */
654 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
655 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
657 /* Marshall data and send request */
659 init_samr_q_enum_dom_groups(&q
, pol
, *start_idx
, size
);
661 if (!samr_io_q_enum_dom_groups("", &q
, &qbuf
, 0) ||
662 !rpc_api_pipe_req(cli
, SAMR_ENUM_DOM_GROUPS
, &qbuf
, &rbuf
))
665 /* Unmarshall response */
667 if (!samr_io_r_enum_dom_groups("", &r
, &rbuf
, 0))
670 /* Return output parameters */
674 if (!NT_STATUS_IS_OK(result
) &&
675 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
678 *num_dom_groups
= r
.num_entries2
;
680 if (*num_dom_groups
== 0)
683 if (!((*dom_groups
) = (struct acct_info
*)
684 talloc(mem_ctx
, sizeof(struct acct_info
) * *num_dom_groups
))) {
685 result
= NT_STATUS_NO_MEMORY
;
689 memset(*dom_groups
, 0, sizeof(struct acct_info
) * (*num_dom_groups
));
693 for (i
= 0; i
< *num_dom_groups
; i
++) {
695 (*dom_groups
)[i
].rid
= r
.sam
[i
].rid
;
697 if (r
.sam
[i
].hdr_name
.buffer
) {
698 unistr2_to_ascii((*dom_groups
)[i
].acct_name
,
699 &r
.uni_grp_name
[name_idx
],
700 sizeof(fstring
) - 1);
704 *start_idx
= r
.next_idx
;
714 /* Enumerate domain groups */
716 NTSTATUS
cli_samr_enum_als_groups(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
717 POLICY_HND
*pol
, uint32
*start_idx
,
718 uint32 size
, struct acct_info
**dom_aliases
,
719 uint32
*num_dom_aliases
)
721 prs_struct qbuf
, rbuf
;
722 SAMR_Q_ENUM_DOM_ALIASES q
;
723 SAMR_R_ENUM_DOM_ALIASES r
;
724 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
730 /* Initialise parse structures */
732 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
733 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
735 /* Marshall data and send request */
737 init_samr_q_enum_dom_aliases(&q
, pol
, *start_idx
, size
);
739 if (!samr_io_q_enum_dom_aliases("", &q
, &qbuf
, 0) ||
740 !rpc_api_pipe_req(cli
, SAMR_ENUM_DOM_ALIASES
, &qbuf
, &rbuf
)) {
744 /* Unmarshall response */
746 if (!samr_io_r_enum_dom_aliases("", &r
, &rbuf
, 0)) {
750 /* Return output parameters */
754 if (!NT_STATUS_IS_OK(result
) &&
755 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
759 *num_dom_aliases
= r
.num_entries2
;
761 if (*num_dom_aliases
== 0)
764 if (!((*dom_aliases
) = (struct acct_info
*)
765 talloc(mem_ctx
, sizeof(struct acct_info
) * *num_dom_aliases
))) {
766 result
= NT_STATUS_NO_MEMORY
;
770 memset(*dom_aliases
, 0, sizeof(struct acct_info
) * *num_dom_aliases
);
774 for (i
= 0; i
< *num_dom_aliases
; i
++) {
776 (*dom_aliases
)[i
].rid
= r
.sam
[i
].rid
;
778 if (r
.sam
[i
].hdr_name
.buffer
) {
779 unistr2_to_ascii((*dom_aliases
)[i
].acct_name
,
780 &r
.uni_grp_name
[name_idx
],
781 sizeof(fstring
) - 1);
785 *start_idx
= r
.next_idx
;
795 /* Query alias members */
797 NTSTATUS
cli_samr_query_aliasmem(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
798 POLICY_HND
*alias_pol
, uint32
*num_mem
,
801 prs_struct qbuf
, rbuf
;
802 SAMR_Q_QUERY_ALIASMEM q
;
803 SAMR_R_QUERY_ALIASMEM r
;
804 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
810 /* Initialise parse structures */
812 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
813 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
815 /* Marshall data and send request */
817 init_samr_q_query_aliasmem(&q
, alias_pol
);
819 if (!samr_io_q_query_aliasmem("", &q
, &qbuf
, 0) ||
820 !rpc_api_pipe_req(cli
, SAMR_QUERY_ALIASMEM
, &qbuf
, &rbuf
)) {
824 /* Unmarshall response */
826 if (!samr_io_r_query_aliasmem("", &r
, &rbuf
, 0)) {
830 /* Return output parameters */
832 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
836 *num_mem
= r
.num_sids
;
838 if (!(*sids
= talloc(mem_ctx
, sizeof(DOM_SID
) * *num_mem
))) {
839 result
= NT_STATUS_UNSUCCESSFUL
;
843 for (i
= 0; i
< *num_mem
; i
++) {
844 (*sids
)[i
] = r
.sid
[i
].sid
;
854 /* Open handle on an alias */
856 NTSTATUS
cli_samr_open_alias(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
857 POLICY_HND
*domain_pol
, uint32 access_mask
,
858 uint32 alias_rid
, POLICY_HND
*alias_pol
)
860 prs_struct qbuf
, rbuf
;
868 /* Initialise parse structures */
870 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
871 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
873 /* Marshall data and send request */
875 init_samr_q_open_alias(&q
, domain_pol
, access_mask
, alias_rid
);
877 if (!samr_io_q_open_alias("", &q
, &qbuf
, 0) ||
878 !rpc_api_pipe_req(cli
, SAMR_OPEN_ALIAS
, &qbuf
, &rbuf
)) {
879 result
= NT_STATUS_UNSUCCESSFUL
;
883 /* Unmarshall response */
885 if (!samr_io_r_open_alias("", &r
, &rbuf
, 0)) {
886 result
= NT_STATUS_UNSUCCESSFUL
;
890 /* Return output parameters */
892 if (NT_STATUS_IS_OK(result
= r
.status
)) {
895 alias_pol
->marker
= malloc(1);
906 /* Query domain info */
908 NTSTATUS
cli_samr_query_dom_info(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
909 POLICY_HND
*domain_pol
, uint16 switch_value
,
912 prs_struct qbuf
, rbuf
;
913 SAMR_Q_QUERY_DOMAIN_INFO q
;
914 SAMR_R_QUERY_DOMAIN_INFO r
;
915 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
920 /* Initialise parse structures */
922 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
923 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
925 /* Marshall data and send request */
927 init_samr_q_query_dom_info(&q
, domain_pol
, switch_value
);
929 if (!samr_io_q_query_dom_info("", &q
, &qbuf
, 0) ||
930 !rpc_api_pipe_req(cli
, SAMR_QUERY_DOMAIN_INFO
, &qbuf
, &rbuf
)) {
934 /* Unmarshall response */
938 if (!samr_io_r_query_dom_info("", &r
, &rbuf
, 0)) {
942 /* Return output parameters */
944 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
955 /* This function returns the bizzare set of (max_entries, max_size) required
956 for the QueryDisplayInfo RPC to actually work against a domain controller
957 with large (10k and higher) numbers of users. These values were
958 obtained by inspection using ethereal and NT4 running User Manager. */
960 void get_query_dispinfo_params(int loop_count
, uint32
*max_entries
,
980 default: /* loop_count >= 4 */
987 /* Query display info */
989 NTSTATUS
cli_samr_query_dispinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
990 POLICY_HND
*domain_pol
, uint32
*start_idx
,
991 uint16 switch_value
, uint32
*num_entries
,
992 uint32 max_entries
, uint32 max_size
,
993 SAM_DISPINFO_CTR
*ctr
)
995 prs_struct qbuf
, rbuf
;
996 SAMR_Q_QUERY_DISPINFO q
;
997 SAMR_R_QUERY_DISPINFO r
;
998 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1005 /* Initialise parse structures */
1007 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1008 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1010 /* Marshall data and send request */
1012 init_samr_q_query_dispinfo(&q
, domain_pol
, switch_value
,
1013 *start_idx
, max_entries
, max_size
);
1015 if (!samr_io_q_query_dispinfo("", &q
, &qbuf
, 0) ||
1016 !rpc_api_pipe_req(cli
, SAMR_QUERY_DISPINFO
, &qbuf
, &rbuf
)) {
1020 /* Unmarshall response */
1024 if (!samr_io_r_query_dispinfo("", &r
, &rbuf
, 0)) {
1028 /* Return output parameters */
1032 if (!NT_STATUS_IS_OK(result
) &&
1033 NT_STATUS_V(result
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
1037 *num_entries
= r
.num_entries
;
1038 *start_idx
+= r
.num_entries
; /* No next_idx in this structure! */
1041 prs_mem_free(&qbuf
);
1042 prs_mem_free(&rbuf
);
1047 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
1048 looked up in one packet. */
1050 NTSTATUS
cli_samr_lookup_rids(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1051 POLICY_HND
*domain_pol
, uint32 flags
,
1052 uint32 num_rids
, uint32
*rids
,
1053 uint32
*num_names
, char ***names
,
1054 uint32
**name_types
)
1056 prs_struct qbuf
, rbuf
;
1057 SAMR_Q_LOOKUP_RIDS q
;
1058 SAMR_R_LOOKUP_RIDS r
;
1059 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1062 if (num_rids
> 1000) {
1063 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1064 "more than ~1000 rids are looked up at once.\n"));
1070 /* Initialise parse structures */
1072 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1073 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1075 /* Marshall data and send request */
1077 init_samr_q_lookup_rids(mem_ctx
, &q
, domain_pol
, flags
,
1080 if (!samr_io_q_lookup_rids("", &q
, &qbuf
, 0) ||
1081 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_RIDS
, &qbuf
, &rbuf
)) {
1085 /* Unmarshall response */
1087 if (!samr_io_r_lookup_rids("", &r
, &rbuf
, 0)) {
1091 /* Return output parameters */
1093 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1097 if (r
.num_names1
== 0) {
1103 *num_names
= r
.num_names1
;
1104 *names
= talloc(mem_ctx
, sizeof(char *) * r
.num_names1
);
1105 *name_types
= talloc(mem_ctx
, sizeof(uint32
) * r
.num_names1
);
1107 for (i
= 0; i
< r
.num_names1
; i
++) {
1110 unistr2_to_ascii(tmp
, &r
.uni_name
[i
], sizeof(tmp
) - 1);
1111 (*names
)[i
] = talloc_strdup(mem_ctx
, tmp
);
1112 (*name_types
)[i
] = r
.type
[i
];
1116 prs_mem_free(&qbuf
);
1117 prs_mem_free(&rbuf
);
1124 NTSTATUS
cli_samr_lookup_names(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1125 POLICY_HND
*domain_pol
, uint32 flags
,
1126 uint32 num_names
, const char **names
,
1127 uint32
*num_rids
, uint32
**rids
,
1130 prs_struct qbuf
, rbuf
;
1131 SAMR_Q_LOOKUP_NAMES q
;
1132 SAMR_R_LOOKUP_NAMES r
;
1133 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1139 /* Initialise parse structures */
1141 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1142 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1144 /* Marshall data and send request */
1146 init_samr_q_lookup_names(mem_ctx
, &q
, domain_pol
, flags
,
1149 if (!samr_io_q_lookup_names("", &q
, &qbuf
, 0) ||
1150 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_NAMES
, &qbuf
, &rbuf
)) {
1154 /* Unmarshall response */
1156 if (!samr_io_r_lookup_names("", &r
, &rbuf
, 0)) {
1160 /* Return output parameters */
1162 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1166 if (r
.num_rids1
== 0) {
1171 *num_rids
= r
.num_rids1
;
1172 *rids
= talloc(mem_ctx
, sizeof(uint32
) * r
.num_rids1
);
1173 *rid_types
= talloc(mem_ctx
, sizeof(uint32
) * r
.num_rids1
);
1175 for (i
= 0; i
< r
.num_rids1
; i
++) {
1176 (*rids
)[i
] = r
.rids
[i
];
1177 (*rid_types
)[i
] = r
.types
[i
];
1181 prs_mem_free(&qbuf
);
1182 prs_mem_free(&rbuf
);
1187 /* Create a domain user */
1189 NTSTATUS
cli_samr_create_dom_user(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1190 POLICY_HND
*domain_pol
, const char *acct_name
,
1191 uint32 acb_info
, uint32 unknown
,
1192 POLICY_HND
*user_pol
, uint32
*rid
)
1194 prs_struct qbuf
, rbuf
;
1195 SAMR_Q_CREATE_USER q
;
1196 SAMR_R_CREATE_USER r
;
1197 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1202 /* Initialise parse structures */
1204 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1205 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1207 /* Marshall data and send request */
1209 init_samr_q_create_user(&q
, domain_pol
, acct_name
, acb_info
, unknown
);
1211 if (!samr_io_q_create_user("", &q
, &qbuf
, 0) ||
1212 !rpc_api_pipe_req(cli
, SAMR_CREATE_USER
, &qbuf
, &rbuf
)) {
1216 /* Unmarshall response */
1218 if (!samr_io_r_create_user("", &r
, &rbuf
, 0)) {
1222 /* Return output parameters */
1224 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1229 *user_pol
= r
.user_pol
;
1235 prs_mem_free(&qbuf
);
1236 prs_mem_free(&rbuf
);
1243 NTSTATUS
cli_samr_set_userinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1244 POLICY_HND
*user_pol
, uint16 switch_value
,
1245 uchar sess_key
[16], SAM_USERINFO_CTR
*ctr
)
1247 prs_struct qbuf
, rbuf
;
1248 SAMR_Q_SET_USERINFO q
;
1249 SAMR_R_SET_USERINFO r
;
1250 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1255 /* Initialise parse structures */
1257 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1258 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1260 /* Marshall data and send request */
1264 init_samr_q_set_userinfo(&q
, user_pol
, sess_key
, switch_value
,
1267 if (!samr_io_q_set_userinfo("", &q
, &qbuf
, 0) ||
1268 !rpc_api_pipe_req(cli
, SAMR_SET_USERINFO
, &qbuf
, &rbuf
)) {
1272 /* Unmarshall response */
1274 if (!samr_io_r_set_userinfo("", &r
, &rbuf
, 0)) {
1278 /* Return output parameters */
1280 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1285 prs_mem_free(&qbuf
);
1286 prs_mem_free(&rbuf
);
1293 NTSTATUS
cli_samr_set_userinfo2(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1294 POLICY_HND
*user_pol
, uint16 switch_value
,
1295 uchar sess_key
[16], SAM_USERINFO_CTR
*ctr
)
1297 prs_struct qbuf
, rbuf
;
1298 SAMR_Q_SET_USERINFO2 q
;
1299 SAMR_R_SET_USERINFO2 r
;
1300 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1305 /* Initialise parse structures */
1307 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1308 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1310 /* Marshall data and send request */
1312 init_samr_q_set_userinfo2(&q
, user_pol
, sess_key
, switch_value
, ctr
);
1314 if (!samr_io_q_set_userinfo2("", &q
, &qbuf
, 0) ||
1315 !rpc_api_pipe_req(cli
, SAMR_SET_USERINFO2
, &qbuf
, &rbuf
)) {
1319 /* Unmarshall response */
1321 if (!samr_io_r_set_userinfo2("", &r
, &rbuf
, 0)) {
1325 /* Return output parameters */
1327 if (!NT_STATUS_IS_OK(result
= r
.status
)) {
1332 prs_mem_free(&qbuf
);
1333 prs_mem_free(&rbuf
);
1338 /* Delete domain user */
1340 NTSTATUS
cli_samr_delete_dom_user(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1341 POLICY_HND
*user_pol
)
1343 prs_struct qbuf
, rbuf
;
1344 SAMR_Q_DELETE_DOM_USER q
;
1345 SAMR_R_DELETE_DOM_USER r
;
1346 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1351 /* Initialise parse structures */
1353 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1354 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1356 /* Marshall data and send request */
1358 init_samr_q_delete_dom_user(&q
, user_pol
);
1360 if (!samr_io_q_delete_dom_user("", &q
, &qbuf
, 0) ||
1361 !rpc_api_pipe_req(cli
, SAMR_DELETE_DOM_USER
, &qbuf
, &rbuf
)) {
1365 /* Unmarshall response */
1367 if (!samr_io_r_delete_dom_user("", &r
, &rbuf
, 0)) {
1371 /* Return output parameters */
1376 prs_mem_free(&qbuf
);
1377 prs_mem_free(&rbuf
);
1382 /* Query user security object */
1384 NTSTATUS
cli_samr_query_sec_obj(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1385 POLICY_HND
*user_pol
, uint16 switch_value
,
1386 TALLOC_CTX
*ctx
, SEC_DESC_BUF
**sec_desc_buf
)
1388 prs_struct qbuf
, rbuf
;
1389 SAMR_Q_QUERY_SEC_OBJ q
;
1390 SAMR_R_QUERY_SEC_OBJ r
;
1391 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1396 /* Initialise parse structures */
1398 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1399 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1401 /* Marshall data and send request */
1403 init_samr_q_query_sec_obj(&q
, user_pol
, switch_value
);
1405 if (!samr_io_q_query_sec_obj("", &q
, &qbuf
, 0) ||
1406 !rpc_api_pipe_req(cli
, SAMR_QUERY_SEC_OBJECT
, &qbuf
, &rbuf
)) {
1410 /* Unmarshall response */
1412 if (!samr_io_r_query_sec_obj("", &r
, &rbuf
, 0)) {
1416 /* Return output parameters */
1419 *sec_desc_buf
=dup_sec_desc_buf(ctx
, r
.buf
);
1422 prs_mem_free(&qbuf
);
1423 prs_mem_free(&rbuf
);
1428 /* Get domain password info */
1430 NTSTATUS
cli_samr_get_dom_pwinfo(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1431 uint16
*unk_0
, uint16
*unk_1
, uint16
*unk_2
)
1433 prs_struct qbuf
, rbuf
;
1434 SAMR_Q_GET_DOM_PWINFO q
;
1435 SAMR_R_GET_DOM_PWINFO r
;
1436 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1441 /* Initialise parse structures */
1443 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1444 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1446 /* Marshall data and send request */
1448 init_samr_q_get_dom_pwinfo(&q
, cli
->desthost
);
1450 if (!samr_io_q_get_dom_pwinfo("", &q
, &qbuf
, 0) ||
1451 !rpc_api_pipe_req(cli
, SAMR_GET_DOM_PWINFO
, &qbuf
, &rbuf
))
1454 /* Unmarshall response */
1456 if (!samr_io_r_get_dom_pwinfo("", &r
, &rbuf
, 0))
1459 /* Return output parameters */
1463 if (NT_STATUS_IS_OK(result
)) {
1473 prs_mem_free(&qbuf
);
1474 prs_mem_free(&rbuf
);
1479 /* Lookup Domain Name */
1481 NTSTATUS
cli_samr_lookup_domain(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1482 POLICY_HND
*user_pol
, char *domain_name
,
1485 prs_struct qbuf
, rbuf
;
1486 SAMR_Q_LOOKUP_DOMAIN q
;
1487 SAMR_R_LOOKUP_DOMAIN r
;
1488 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1493 /* Initialise parse structures */
1495 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
1496 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
1498 /* Marshall data and send request */
1500 init_samr_q_lookup_domain(&q
, user_pol
, domain_name
);
1502 if (!samr_io_q_lookup_domain("", &q
, &qbuf
, 0) ||
1503 !rpc_api_pipe_req(cli
, SAMR_LOOKUP_DOMAIN
, &qbuf
, &rbuf
))
1506 /* Unmarshall response */
1508 if (!samr_io_r_lookup_domain("", &r
, &rbuf
, 0))
1511 /* Return output parameters */
1515 if (NT_STATUS_IS_OK(result
))
1516 sid_copy(sid
, &r
.dom_sid
.sid
);
1519 prs_mem_free(&qbuf
);
1520 prs_mem_free(&rbuf
);