2 Unix SMB/Netbios implementation.
5 Copyright (C) Tim Potter 2000,
6 Copyright (C) Andrew Tridgell 1992-1997,2000,
7 Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
8 Copyright (C) Paul Ashton 1997,2000,
9 Copyright (C) Elrond 2000.
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 /* Opens a SMB connection to the SAMR pipe */
30 struct cli_state
*cli_samr_initialise(struct cli_state
*cli
, char *system_name
,
31 struct ntuser_creds
*creds
)
33 struct in_addr dest_ip
;
34 struct nmb_name calling
, called
;
36 extern pstring global_myname
;
37 struct ntuser_creds anon
;
39 /* Initialise cli_state information */
41 if (!cli_initialise(cli
)) {
47 anon
.pwd
.null_pwd
= 1;
51 cli_init_creds(cli
, creds
);
53 /* Establish a SMB connection */
55 if (!resolve_srv_name(system_name
, dest_host
, &dest_ip
)) {
59 make_nmb_name(&called
, dns_to_netbios_name(dest_host
), 0x20);
60 make_nmb_name(&calling
, dns_to_netbios_name(global_myname
), 0);
62 if (!cli_establish_connection(cli
, dest_host
, &dest_ip
, &calling
,
63 &called
, "IPC$", "IPC", False
, True
)) {
67 /* Open a NT session thingy */
69 if (!cli_nt_session_open(cli
, PIPE_SAMR
)) {
77 /* Shut down a SMB connection to the SAMR pipe */
79 void cli_samr_shutdown(struct cli_state
*cli
)
81 if (cli
->fd
!= -1) cli_ulogoff(cli
);
85 /* Connect to SAMR database */
87 uint32
cli_samr_connect(
88 struct cli_state
*cli
,
92 POLICY_HND
*connect_pol
95 prs_struct qbuf
, rbuf
;
103 /* Initialise parse structures */
105 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
106 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
108 /* Marshall data and send request */
110 init_samr_q_connect(&q
, srv_name
, access_mask
);
112 if (!samr_io_q_connect("", &q
, &qbuf
, 0) ||
113 !rpc_api_pipe_req(cli
, SAMR_CONNECT
, &qbuf
, &rbuf
)) {
114 result
= NT_STATUS_UNSUCCESSFUL
;
118 /* Unmarshall response */
120 if (!samr_io_r_connect("", &r
, &rbuf
, 0)) {
121 result
= NT_STATUS_UNSUCCESSFUL
;
125 /* Return output parameters */
127 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
128 *connect_pol
= r
.connect_pol
;
138 /* Close SAMR handle */
140 uint32
cli_samr_close(
141 struct cli_state
*cli
,
143 POLICY_HND
*connect_pol
146 prs_struct qbuf
, rbuf
;
154 /* Initialise parse structures */
156 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
157 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
159 /* Marshall data and send request */
161 init_samr_q_close_hnd(&q
, connect_pol
);
163 if (!samr_io_q_close_hnd("", &q
, &qbuf
, 0) ||
164 !rpc_api_pipe_req(cli
, SAMR_CLOSE_HND
, &qbuf
, &rbuf
)) {
165 result
= NT_STATUS_UNSUCCESSFUL
;
169 /* Unmarshall response */
171 if (!samr_io_r_close_hnd("", &r
, &rbuf
, 0)) {
172 result
= NT_STATUS_UNSUCCESSFUL
;
176 /* Return output parameters */
178 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
179 *connect_pol
= r
.pol
;
189 /* Open handle on a domain */
191 uint32
cli_samr_open_domain(
192 struct cli_state
*cli
,
194 POLICY_HND
*connect_pol
,
197 POLICY_HND
*domain_pol
200 prs_struct qbuf
, rbuf
;
201 SAMR_Q_OPEN_DOMAIN q
;
202 SAMR_R_OPEN_DOMAIN r
;
208 /* Initialise parse structures */
210 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
211 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
213 /* Marshall data and send request */
215 init_samr_q_open_domain(&q
, connect_pol
, access_mask
, domain_sid
);
217 if (!samr_io_q_open_domain("", &q
, &qbuf
, 0) ||
218 !rpc_api_pipe_req(cli
, SAMR_OPEN_DOMAIN
, &qbuf
, &rbuf
)) {
219 result
= NT_STATUS_UNSUCCESSFUL
;
223 /* Unmarshall response */
225 if (!samr_io_r_open_domain("", &r
, &rbuf
, 0)) {
226 result
= NT_STATUS_UNSUCCESSFUL
;
230 /* Return output parameters */
232 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
233 *domain_pol
= r
.domain_pol
;
243 /* Open handle on a user */
245 uint32
cli_samr_open_user(
246 struct cli_state
*cli
,
248 POLICY_HND
*domain_pol
,
254 prs_struct qbuf
, rbuf
;
262 /* Initialise parse structures */
264 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
265 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
267 /* Marshall data and send request */
269 init_samr_q_open_user(&q
, domain_pol
, access_mask
, user_rid
);
271 if (!samr_io_q_open_user("", &q
, &qbuf
, 0) ||
272 !rpc_api_pipe_req(cli
, SAMR_OPEN_USER
, &qbuf
, &rbuf
)) {
273 result
= NT_STATUS_UNSUCCESSFUL
;
277 /* Unmarshall response */
279 if (!samr_io_r_open_user("", &r
, &rbuf
, 0)) {
280 result
= NT_STATUS_UNSUCCESSFUL
;
284 /* Return output parameters */
286 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
287 *user_pol
= r
.user_pol
;
297 /* Open handle on a group */
299 uint32
cli_samr_open_group(
300 struct cli_state
*cli
,
302 POLICY_HND
*domain_pol
,
305 POLICY_HND
*group_pol
308 prs_struct qbuf
, rbuf
;
316 /* Initialise parse structures */
318 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
319 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
321 /* Marshall data and send request */
323 init_samr_q_open_group(&q
, domain_pol
, access_mask
, group_rid
);
325 if (!samr_io_q_open_group("", &q
, &qbuf
, 0) ||
326 !rpc_api_pipe_req(cli
, SAMR_OPEN_GROUP
, &qbuf
, &rbuf
)) {
327 result
= NT_STATUS_UNSUCCESSFUL
;
331 /* Unmarshall response */
333 if (!samr_io_r_open_group("", &r
, &rbuf
, 0)) {
334 result
= NT_STATUS_UNSUCCESSFUL
;
338 /* Return output parameters */
340 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
351 /* Query user info */
353 uint32
cli_samr_query_userinfo(
354 struct cli_state
*cli
,
356 POLICY_HND
*user_pol
,
358 SAM_USERINFO_CTR
*ctr
361 prs_struct qbuf
, rbuf
;
362 SAMR_Q_QUERY_USERINFO q
;
363 SAMR_R_QUERY_USERINFO r
;
369 /* Initialise parse structures */
371 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
372 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
374 /* Marshall data and send request */
376 init_samr_q_query_userinfo(&q
, user_pol
, switch_value
);
378 if (!samr_io_q_query_userinfo("", &q
, &qbuf
, 0) ||
379 !rpc_api_pipe_req(cli
, SAMR_QUERY_USERINFO
, &qbuf
, &rbuf
)) {
380 result
= NT_STATUS_UNSUCCESSFUL
;
384 /* Unmarshall response */
388 if (!samr_io_r_query_userinfo("", &r
, &rbuf
, 0)) {
389 result
= NT_STATUS_UNSUCCESSFUL
;
393 /* Return output parameters */
404 /* Query group info */
406 uint32
cli_samr_query_groupinfo(
407 struct cli_state
*cli
,
409 POLICY_HND
*group_pol
,
414 prs_struct qbuf
, rbuf
;
415 SAMR_Q_QUERY_GROUPINFO q
;
416 SAMR_R_QUERY_GROUPINFO r
;
422 /* Initialise parse structures */
424 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
425 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
427 /* Marshall data and send request */
429 init_samr_q_query_groupinfo(&q
, group_pol
, info_level
);
431 if (!samr_io_q_query_groupinfo("", &q
, &qbuf
, 0) ||
432 !rpc_api_pipe_req(cli
, SAMR_QUERY_GROUPINFO
, &qbuf
, &rbuf
)) {
433 result
= NT_STATUS_UNSUCCESSFUL
;
437 /* Unmarshall response */
441 if (!samr_io_r_query_groupinfo("", &r
, &rbuf
, 0)) {
442 result
= NT_STATUS_UNSUCCESSFUL
;
446 /* Return output parameters */
457 /* Query user groups */
459 uint32
cli_samr_query_usergroups(
460 struct cli_state
*cli
,
462 POLICY_HND
*user_pol
,
467 prs_struct qbuf
, rbuf
;
468 SAMR_Q_QUERY_USERGROUPS q
;
469 SAMR_R_QUERY_USERGROUPS r
;
475 /* Initialise parse structures */
477 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
478 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
480 /* Marshall data and send request */
482 init_samr_q_query_usergroups(&q
, user_pol
);
484 if (!samr_io_q_query_usergroups("", &q
, &qbuf
, 0) ||
485 !rpc_api_pipe_req(cli
, SAMR_QUERY_USERGROUPS
, &qbuf
, &rbuf
)) {
486 result
= NT_STATUS_UNSUCCESSFUL
;
490 /* Unmarshall response */
492 if (!samr_io_r_query_usergroups("", &r
, &rbuf
, 0)) {
493 result
= NT_STATUS_UNSUCCESSFUL
;
497 /* Return output parameters */
499 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
500 *num_groups
= r
.num_entries
;
511 /* Query user groups */
513 uint32
cli_samr_query_groupmem(
514 struct cli_state
*cli
,
516 POLICY_HND
*group_pol
,
522 prs_struct qbuf
, rbuf
;
523 SAMR_Q_QUERY_GROUPMEM q
;
524 SAMR_R_QUERY_GROUPMEM r
;
530 /* Initialise parse structures */
532 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
533 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
535 /* Marshall data and send request */
537 init_samr_q_query_groupmem(&q
, group_pol
);
539 if (!samr_io_q_query_groupmem("", &q
, &qbuf
, 0) ||
540 !rpc_api_pipe_req(cli
, SAMR_QUERY_GROUPMEM
, &qbuf
, &rbuf
)) {
541 result
= NT_STATUS_UNSUCCESSFUL
;
545 /* Unmarshall response */
547 if (!samr_io_r_query_groupmem("", &r
, &rbuf
, 0)) {
548 result
= NT_STATUS_UNSUCCESSFUL
;
552 /* Return output parameters */
554 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {
555 *num_mem
= r
.num_entries
;
567 /* Enumerate domain groups */
569 uint32
cli_samr_enum_dom_groups(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
570 POLICY_HND
*pol
, uint32
*start_idx
,
571 uint32 size
, struct acct_info
**dom_groups
,
572 uint32
*num_dom_groups
)
574 prs_struct qbuf
, rbuf
;
575 SAMR_Q_ENUM_DOM_GROUPS q
;
576 SAMR_R_ENUM_DOM_GROUPS r
;
577 uint32 result
= NT_STATUS_UNSUCCESSFUL
, name_idx
, i
;
582 /* Initialise parse structures */
584 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
585 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
587 /* Marshall data and send request */
589 init_samr_q_enum_dom_groups(&q
, pol
, *start_idx
, size
);
591 if (!samr_io_q_enum_dom_groups("", &q
, &qbuf
, 0) ||
592 !rpc_api_pipe_req(cli
, SAMR_ENUM_DOM_GROUPS
, &qbuf
, &rbuf
)) {
596 /* Unmarshall response */
598 if (!samr_io_r_enum_dom_groups("", &r
, &rbuf
, 0)) {
602 /* Return output parameters */
606 if (result
!= NT_STATUS_NOPROBLEMO
&&
607 result
!= STATUS_MORE_ENTRIES
) {
611 *num_dom_groups
= r
.num_entries2
;
613 if (!((*dom_groups
) = (struct acct_info
*)
614 talloc(mem_ctx
, sizeof(struct acct_info
) * *num_dom_groups
))) {
615 result
= NT_STATUS_UNSUCCESSFUL
;
619 memset(*dom_groups
, 0, sizeof(struct acct_info
) * *num_dom_groups
);
623 for (i
= 0; i
< *num_dom_groups
; i
++) {
625 (*dom_groups
)[i
].rid
= r
.sam
[i
].rid
;
627 if (r
.sam
[i
].hdr_name
.buffer
) {
628 unistr2_to_ascii((*dom_groups
)[i
].acct_name
,
629 &r
.uni_grp_name
[name_idx
],
630 sizeof(fstring
) - 1);
634 *start_idx
= r
.next_idx
;
644 /* Query alias members */
646 uint32
cli_samr_query_aliasmem(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
647 POLICY_HND
*alias_pol
, uint32
*num_mem
,
650 prs_struct qbuf
, rbuf
;
651 SAMR_Q_QUERY_ALIASMEM q
;
652 SAMR_R_QUERY_ALIASMEM r
;
653 uint32 result
= NT_STATUS_UNSUCCESSFUL
, i
;
658 /* Initialise parse structures */
660 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
661 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
663 /* Marshall data and send request */
665 init_samr_q_query_aliasmem(&q
, alias_pol
);
667 if (!samr_io_q_query_aliasmem("", &q
, &qbuf
, 0) ||
668 !rpc_api_pipe_req(cli
, SAMR_QUERY_ALIASMEM
, &qbuf
, &rbuf
)) {
672 /* Unmarshall response */
674 if (!samr_io_r_query_aliasmem("", &r
, &rbuf
, 0)) {
678 /* Return output parameters */
680 if ((result
= r
.status
) != NT_STATUS_NOPROBLEMO
) {
684 *num_mem
= r
.num_sids
;
686 if (!(*sids
= talloc(mem_ctx
, sizeof(DOM_SID
) * *num_mem
))) {
687 result
= NT_STATUS_UNSUCCESSFUL
;
691 for (i
= 0; i
< *num_mem
; i
++) {
692 (*sids
)[i
] = r
.sid
[i
].sid
;
702 /* Open handle on an alias */
704 uint32
cli_samr_open_alias(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
705 POLICY_HND
*domain_pol
, uint32 access_mask
,
706 uint32 alias_rid
, POLICY_HND
*alias_pol
)
708 prs_struct qbuf
, rbuf
;
716 /* Initialise parse structures */
718 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
719 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
721 /* Marshall data and send request */
723 init_samr_q_open_alias(&q
, domain_pol
, access_mask
, alias_rid
);
725 if (!samr_io_q_open_alias("", &q
, &qbuf
, 0) ||
726 !rpc_api_pipe_req(cli
, SAMR_OPEN_ALIAS
, &qbuf
, &rbuf
)) {
727 result
= NT_STATUS_UNSUCCESSFUL
;
731 /* Unmarshall response */
733 if (!samr_io_r_open_alias("", &r
, &rbuf
, 0)) {
734 result
= NT_STATUS_UNSUCCESSFUL
;
738 /* Return output parameters */
740 if ((result
= r
.status
) == NT_STATUS_NOPROBLEMO
) {