few edits
[Samba.git] / source / libsmb / cli_samr.c
blobfbcc650b010b6666c32db1d4804782e1f48d8ae5
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
4 Copyright (C) Tim Potter 2000-2001,
5 Copyright (C) Andrew Tridgell 1992-1997,2000,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
7 Copyright (C) Paul Ashton 1997,2000,
8 Copyright (C) Elrond 2000.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 /* Opens a SMB connection to the SAMR pipe */
29 struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
30 struct ntuser_creds *creds)
32 return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds);
35 /* Connect to SAMR database */
37 NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
38 uint32 access_mask, POLICY_HND *connect_pol)
40 prs_struct qbuf, rbuf;
41 SAMR_Q_CONNECT q;
42 SAMR_R_CONNECT r;
43 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
45 ZERO_STRUCT(q);
46 ZERO_STRUCT(r);
48 /* Initialise parse structures */
50 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
51 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
53 /* Marshall data and send request */
55 init_samr_q_connect(&q, cli->desthost, access_mask);
57 if (!samr_io_q_connect("", &q, &qbuf, 0) ||
58 !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) {
59 goto done;
62 /* Unmarshall response */
64 if (!samr_io_r_connect("", &r, &rbuf, 0)) {
65 goto done;
68 /* Return output parameters */
70 if (NT_STATUS_IS_OK(result = r.status)) {
71 *connect_pol = r.connect_pol;
74 done:
75 prs_mem_free(&qbuf);
76 prs_mem_free(&rbuf);
78 return result;
81 /* Close SAMR handle */
83 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
84 POLICY_HND *connect_pol)
86 prs_struct qbuf, rbuf;
87 SAMR_Q_CLOSE_HND q;
88 SAMR_R_CLOSE_HND r;
89 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
91 ZERO_STRUCT(q);
92 ZERO_STRUCT(r);
94 /* Initialise parse structures */
96 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
97 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
99 /* Marshall data and send request */
101 init_samr_q_close_hnd(&q, connect_pol);
103 if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
104 !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) {
105 goto done;
108 /* Unmarshall response */
110 if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) {
111 goto done;
114 /* Return output parameters */
116 if (NT_STATUS_IS_OK(result = r.status)) {
117 *connect_pol = r.pol;
120 done:
121 prs_mem_free(&qbuf);
122 prs_mem_free(&rbuf);
124 return result;
127 /* Open handle on a domain */
129 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
130 POLICY_HND *connect_pol, uint32 access_mask,
131 DOM_SID *domain_sid, POLICY_HND *domain_pol)
133 prs_struct qbuf, rbuf;
134 SAMR_Q_OPEN_DOMAIN q;
135 SAMR_R_OPEN_DOMAIN r;
136 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
138 ZERO_STRUCT(q);
139 ZERO_STRUCT(r);
141 /* Initialise parse structures */
143 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
144 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
146 /* Marshall data and send request */
148 init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
150 if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
151 !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) {
152 goto done;
155 /* Unmarshall response */
157 if (!samr_io_r_open_domain("", &r, &rbuf, 0)) {
158 goto done;
161 /* Return output parameters */
163 if (NT_STATUS_IS_OK(result = r.status)) {
164 *domain_pol = r.domain_pol;
167 done:
168 prs_mem_free(&qbuf);
169 prs_mem_free(&rbuf);
171 return result;
174 /* Open handle on a user */
176 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
177 POLICY_HND *domain_pol, uint32 access_mask,
178 uint32 user_rid, POLICY_HND *user_pol)
180 prs_struct qbuf, rbuf;
181 SAMR_Q_OPEN_USER q;
182 SAMR_R_OPEN_USER r;
183 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
185 ZERO_STRUCT(q);
186 ZERO_STRUCT(r);
188 /* Initialise parse structures */
190 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
191 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
193 /* Marshall data and send request */
195 init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
197 if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
198 !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) {
199 goto done;
202 /* Unmarshall response */
204 if (!samr_io_r_open_user("", &r, &rbuf, 0)) {
205 goto done;
208 /* Return output parameters */
210 if (NT_STATUS_IS_OK(result = r.status)) {
211 *user_pol = r.user_pol;
214 done:
215 prs_mem_free(&qbuf);
216 prs_mem_free(&rbuf);
218 return result;
221 /* Open handle on a group */
223 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
224 POLICY_HND *domain_pol, uint32 access_mask,
225 uint32 group_rid, POLICY_HND *group_pol)
227 prs_struct qbuf, rbuf;
228 SAMR_Q_OPEN_GROUP q;
229 SAMR_R_OPEN_GROUP r;
230 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
232 ZERO_STRUCT(q);
233 ZERO_STRUCT(r);
235 /* Initialise parse structures */
237 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
238 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
240 /* Marshall data and send request */
242 init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
244 if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
245 !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) {
246 goto done;
249 /* Unmarshall response */
251 if (!samr_io_r_open_group("", &r, &rbuf, 0)) {
252 goto done;
255 /* Return output parameters */
257 if (NT_STATUS_IS_OK(result = r.status)) {
258 *group_pol = r.pol;
261 done:
262 prs_mem_free(&qbuf);
263 prs_mem_free(&rbuf);
265 return result;
268 /* Query user info */
270 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
271 POLICY_HND *user_pol, uint16 switch_value,
272 SAM_USERINFO_CTR **ctr)
274 prs_struct qbuf, rbuf;
275 SAMR_Q_QUERY_USERINFO q;
276 SAMR_R_QUERY_USERINFO r;
277 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
279 ZERO_STRUCT(q);
280 ZERO_STRUCT(r);
282 /* Initialise parse structures */
284 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
285 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
287 /* Marshall data and send request */
289 init_samr_q_query_userinfo(&q, user_pol, switch_value);
291 if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
292 !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) {
293 goto done;
296 /* Unmarshall response */
298 if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) {
299 goto done;
302 /* Return output parameters */
304 result = r.status;
305 *ctr = r.ctr;
307 done:
308 prs_mem_free(&qbuf);
309 prs_mem_free(&rbuf);
311 return result;
314 /* Query group info */
316 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
317 POLICY_HND *group_pol, uint32 info_level,
318 GROUP_INFO_CTR **ctr)
320 prs_struct qbuf, rbuf;
321 SAMR_Q_QUERY_GROUPINFO q;
322 SAMR_R_QUERY_GROUPINFO r;
323 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
325 ZERO_STRUCT(q);
326 ZERO_STRUCT(r);
328 /* Initialise parse structures */
330 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
331 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
333 /* Marshall data and send request */
335 init_samr_q_query_groupinfo(&q, group_pol, info_level);
337 if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
338 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) {
339 goto done;
342 /* Unmarshall response */
344 if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) {
345 goto done;
348 *ctr = r.ctr;
350 /* Return output parameters */
352 result = r.status;
354 done:
355 prs_mem_free(&qbuf);
356 prs_mem_free(&rbuf);
358 return result;
361 /* Query user groups */
363 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
364 POLICY_HND *user_pol, uint32 *num_groups,
365 DOM_GID **gid)
367 prs_struct qbuf, rbuf;
368 SAMR_Q_QUERY_USERGROUPS q;
369 SAMR_R_QUERY_USERGROUPS r;
370 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
372 ZERO_STRUCT(q);
373 ZERO_STRUCT(r);
375 /* Initialise parse structures */
377 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
378 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
380 /* Marshall data and send request */
382 init_samr_q_query_usergroups(&q, user_pol);
384 if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
385 !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) {
386 goto done;
389 /* Unmarshall response */
391 if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) {
392 goto done;
395 /* Return output parameters */
397 if (NT_STATUS_IS_OK(result = r.status)) {
398 *num_groups = r.num_entries;
399 *gid = r.gid;
402 done:
403 prs_mem_free(&qbuf);
404 prs_mem_free(&rbuf);
406 return result;
409 /* Query user aliases */
411 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
412 POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
413 uint32 *num_aliases, uint32 **als_rids)
415 prs_struct qbuf, rbuf;
416 SAMR_Q_QUERY_USERALIASES q;
417 SAMR_R_QUERY_USERALIASES r;
418 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
419 uint ptr=1;
421 ZERO_STRUCT(q);
422 ZERO_STRUCT(r);
424 /* Initialise parse structures */
426 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
427 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
429 /* Marshall data and send request */
431 init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
433 if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
434 !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) {
435 goto done;
438 /* Unmarshall response */
440 if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) {
441 goto done;
444 /* Return output parameters */
446 if (NT_STATUS_IS_OK(result = r.status)) {
447 *num_aliases = r.num_entries;
448 *als_rids = r.rid;
451 done:
452 prs_mem_free(&qbuf);
453 prs_mem_free(&rbuf);
455 return result;
458 /* Query user groups */
460 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
461 POLICY_HND *group_pol, uint32 *num_mem,
462 uint32 **rid, uint32 **attr)
464 prs_struct qbuf, rbuf;
465 SAMR_Q_QUERY_GROUPMEM q;
466 SAMR_R_QUERY_GROUPMEM r;
467 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
469 ZERO_STRUCT(q);
470 ZERO_STRUCT(r);
472 /* Initialise parse structures */
474 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
475 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
477 /* Marshall data and send request */
479 init_samr_q_query_groupmem(&q, group_pol);
481 if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
482 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) {
483 goto done;
486 /* Unmarshall response */
488 if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) {
489 goto done;
492 /* Return output parameters */
494 if (NT_STATUS_IS_OK(result = r.status)) {
495 *num_mem = r.num_entries;
496 *rid = r.rid;
497 *attr = r.attr;
500 done:
501 prs_mem_free(&qbuf);
502 prs_mem_free(&rbuf);
504 return result;
507 /* Enumerate domain groups */
509 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
510 POLICY_HND *pol, uint32 *start_idx,
511 uint32 size, struct acct_info **dom_groups,
512 uint32 *num_dom_groups)
514 prs_struct qbuf, rbuf;
515 SAMR_Q_ENUM_DOM_GROUPS q;
516 SAMR_R_ENUM_DOM_GROUPS r;
517 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
518 uint32 name_idx, i;
520 ZERO_STRUCT(q);
521 ZERO_STRUCT(r);
523 /* Initialise parse structures */
525 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
526 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
528 /* Marshall data and send request */
530 init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
532 if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
533 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) {
534 goto done;
537 /* Unmarshall response */
539 if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) {
540 goto done;
543 /* Return output parameters */
545 result = r.status;
547 if (!NT_STATUS_IS_OK(result) &&
548 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
549 goto done;
552 *num_dom_groups = r.num_entries2;
554 if (!((*dom_groups) = (struct acct_info *)
555 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
556 result = NT_STATUS_UNSUCCESSFUL;
557 goto done;
560 memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
562 name_idx = 0;
564 for (i = 0; i < *num_dom_groups; i++) {
566 (*dom_groups)[i].rid = r.sam[i].rid;
568 if (r.sam[i].hdr_name.buffer) {
569 unistr2_to_unix((*dom_groups)[i].acct_name,
570 &r.uni_grp_name[name_idx],
571 sizeof(fstring) - 1);
572 name_idx++;
575 *start_idx = r.next_idx;
578 done:
579 prs_mem_free(&qbuf);
580 prs_mem_free(&rbuf);
582 return result;
585 /* Enumerate domain groups */
587 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
588 POLICY_HND *pol, uint32 *start_idx,
589 uint32 size, struct acct_info **dom_groups,
590 uint32 *num_dom_groups)
592 prs_struct qbuf, rbuf;
593 SAMR_Q_ENUM_DOM_ALIASES q;
594 SAMR_R_ENUM_DOM_ALIASES r;
595 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
596 uint32 name_idx, i;
598 ZERO_STRUCT(q);
599 ZERO_STRUCT(r);
601 /* Initialise parse structures */
603 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
604 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
606 /* Marshall data and send request */
608 init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
610 if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
611 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
612 goto done;
615 /* Unmarshall response */
617 if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
618 goto done;
621 /* Return output parameters */
623 result = r.status;
625 if (!NT_STATUS_IS_OK(result) &&
626 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
627 goto done;
630 *num_dom_groups = r.num_entries2;
632 if (!((*dom_groups) = (struct acct_info *)
633 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
634 result = NT_STATUS_UNSUCCESSFUL;
635 goto done;
638 memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
640 name_idx = 0;
642 for (i = 0; i < *num_dom_groups; i++) {
644 (*dom_groups)[i].rid = r.sam[i].rid;
646 if (r.sam[i].hdr_name.buffer) {
647 unistr2_to_unix((*dom_groups)[i].acct_name,
648 &r.uni_grp_name[name_idx],
649 sizeof(fstring) - 1);
650 name_idx++;
653 *start_idx = r.next_idx;
656 done:
657 prs_mem_free(&qbuf);
658 prs_mem_free(&rbuf);
660 return result;
663 /* Query alias members */
665 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
666 POLICY_HND *alias_pol, uint32 *num_mem,
667 DOM_SID **sids)
669 prs_struct qbuf, rbuf;
670 SAMR_Q_QUERY_ALIASMEM q;
671 SAMR_R_QUERY_ALIASMEM r;
672 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
673 uint32 i;
675 ZERO_STRUCT(q);
676 ZERO_STRUCT(r);
678 /* Initialise parse structures */
680 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
681 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
683 /* Marshall data and send request */
685 init_samr_q_query_aliasmem(&q, alias_pol);
687 if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
688 !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
689 goto done;
692 /* Unmarshall response */
694 if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
695 goto done;
698 /* Return output parameters */
700 if (!NT_STATUS_IS_OK(result = r.status)) {
701 goto done;
704 *num_mem = r.num_sids;
706 if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
707 result = NT_STATUS_UNSUCCESSFUL;
708 goto done;
711 for (i = 0; i < *num_mem; i++) {
712 (*sids)[i] = r.sid[i].sid;
715 done:
716 prs_mem_free(&qbuf);
717 prs_mem_free(&rbuf);
719 return result;
722 /* Open handle on an alias */
724 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
725 POLICY_HND *domain_pol, uint32 access_mask,
726 uint32 alias_rid, POLICY_HND *alias_pol)
728 prs_struct qbuf, rbuf;
729 SAMR_Q_OPEN_ALIAS q;
730 SAMR_R_OPEN_ALIAS r;
731 NTSTATUS result;
733 ZERO_STRUCT(q);
734 ZERO_STRUCT(r);
736 /* Initialise parse structures */
738 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
739 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
741 /* Marshall data and send request */
743 init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
745 if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
746 !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
747 result = NT_STATUS_UNSUCCESSFUL;
748 goto done;
751 /* Unmarshall response */
753 if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
754 result = NT_STATUS_UNSUCCESSFUL;
755 goto done;
758 /* Return output parameters */
760 if (NT_STATUS_IS_OK(result = r.status)) {
761 *alias_pol = r.pol;
764 done:
765 prs_mem_free(&qbuf);
766 prs_mem_free(&rbuf);
768 return result;
771 /* Query domain info */
773 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
774 POLICY_HND *domain_pol, uint16 switch_value,
775 SAM_UNK_CTR *ctr)
777 prs_struct qbuf, rbuf;
778 SAMR_Q_QUERY_DOMAIN_INFO q;
779 SAMR_R_QUERY_DOMAIN_INFO r;
780 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
782 ZERO_STRUCT(q);
783 ZERO_STRUCT(r);
785 /* Initialise parse structures */
787 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
788 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
790 /* Marshall data and send request */
792 init_samr_q_query_dom_info(&q, domain_pol, switch_value);
794 if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
795 !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
796 goto done;
799 /* Unmarshall response */
801 r.ctr = ctr;
803 if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
804 goto done;
807 /* Return output parameters */
809 if (!NT_STATUS_IS_OK(result = r.status)) {
810 goto done;
813 done:
814 prs_mem_free(&qbuf);
815 prs_mem_free(&rbuf);
817 return result;
820 /* Query display info */
822 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
823 POLICY_HND *domain_pol, uint32 *start_idx,
824 uint16 switch_value, uint32 *num_entries,
825 uint32 max_entries, SAM_DISPINFO_CTR *ctr)
827 prs_struct qbuf, rbuf;
828 SAMR_Q_QUERY_DISPINFO q;
829 SAMR_R_QUERY_DISPINFO r;
830 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
832 ZERO_STRUCT(q);
833 ZERO_STRUCT(r);
835 /* Initialise parse structures */
837 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
838 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
840 /* Marshall data and send request */
842 init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
843 *start_idx, max_entries);
845 if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
846 !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
847 goto done;
850 /* Unmarshall response */
852 r.ctr = ctr;
854 if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
855 goto done;
858 /* Return output parameters */
860 result = r.status;
862 if (!NT_STATUS_IS_OK(result) &&
863 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
864 goto done;
867 *num_entries = r.num_entries;
868 *start_idx += r.num_entries; /* No next_idx in this structure! */
870 done:
871 prs_mem_free(&qbuf);
872 prs_mem_free(&rbuf);
874 return result;
877 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
878 looked up in one packet. */
880 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
881 POLICY_HND *domain_pol, uint32 flags,
882 uint32 num_rids, uint32 *rids,
883 uint32 *num_names, char ***names,
884 uint32 **name_types)
886 prs_struct qbuf, rbuf;
887 SAMR_Q_LOOKUP_RIDS q;
888 SAMR_R_LOOKUP_RIDS r;
889 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
890 uint32 i;
892 if (num_rids > 1000) {
893 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
894 "more than ~1000 rids are looked up at once.\n"));
897 ZERO_STRUCT(q);
898 ZERO_STRUCT(r);
900 /* Initialise parse structures */
902 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
903 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
905 /* Marshall data and send request */
907 init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
908 num_rids, rids);
910 if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
911 !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
912 goto done;
915 /* Unmarshall response */
917 if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
918 goto done;
921 /* Return output parameters */
923 if (!NT_STATUS_IS_OK(result = r.status)) {
924 goto done;
927 if (r.num_names1 == 0) {
928 *num_names = 0;
929 *names = NULL;
930 goto done;
933 *num_names = r.num_names1;
934 *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
935 *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
937 for (i = 0; i < r.num_names1; i++) {
938 fstring tmp;
940 unistr2_to_unix(tmp, &r.uni_name[i], sizeof(tmp) - 1);
941 (*names)[i] = talloc_strdup(mem_ctx, tmp);
942 (*name_types)[i] = r.type[i];
945 done:
946 prs_mem_free(&qbuf);
947 prs_mem_free(&rbuf);
949 return result;
952 /* Lookup names */
954 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
955 POLICY_HND *domain_pol, uint32 flags,
956 uint32 num_names, char **names,
957 uint32 *num_rids, uint32 **rids,
958 uint32 **rid_types)
960 prs_struct qbuf, rbuf;
961 SAMR_Q_LOOKUP_NAMES q;
962 SAMR_R_LOOKUP_NAMES r;
963 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
964 uint32 i;
966 ZERO_STRUCT(q);
967 ZERO_STRUCT(r);
969 /* Initialise parse structures */
971 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
972 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
974 /* Marshall data and send request */
976 init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
977 num_names, names);
979 if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
980 !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
981 goto done;
984 /* Unmarshall response */
986 if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
987 goto done;
990 /* Return output parameters */
992 if (!NT_STATUS_IS_OK(result = r.status)) {
993 goto done;
996 if (r.num_rids1 == 0) {
997 *num_rids = 0;
998 goto done;
1001 *num_rids = r.num_rids1;
1002 *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1003 *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1005 for (i = 0; i < r.num_rids1; i++) {
1006 (*rids)[i] = r.rids[i];
1007 (*rid_types)[i] = r.types[i];
1010 done:
1011 prs_mem_free(&qbuf);
1012 prs_mem_free(&rbuf);
1014 return result;
1017 /* Create a domain user */
1019 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1020 POLICY_HND *domain_pol, char *acct_name,
1021 uint32 acb_info, uint32 unknown,
1022 POLICY_HND *user_pol, uint32 *rid)
1024 prs_struct qbuf, rbuf;
1025 SAMR_Q_CREATE_USER q;
1026 SAMR_R_CREATE_USER r;
1027 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1029 ZERO_STRUCT(q);
1030 ZERO_STRUCT(r);
1032 /* Initialise parse structures */
1034 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1035 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1037 /* Marshall data and send request */
1039 init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1041 if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1042 !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1043 goto done;
1046 /* Unmarshall response */
1048 if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1049 goto done;
1052 /* Return output parameters */
1054 if (!NT_STATUS_IS_OK(result = r.status)) {
1055 goto done;
1058 if (user_pol)
1059 *user_pol = r.user_pol;
1061 if (rid)
1062 *rid = r.user_rid;
1064 done:
1065 prs_mem_free(&qbuf);
1066 prs_mem_free(&rbuf);
1068 return result;
1071 /* Set userinfo */
1073 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1074 POLICY_HND *user_pol, uint16 switch_value,
1075 uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1077 prs_struct qbuf, rbuf;
1078 SAMR_Q_SET_USERINFO q;
1079 SAMR_R_SET_USERINFO r;
1080 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1082 ZERO_STRUCT(q);
1083 ZERO_STRUCT(r);
1085 /* Initialise parse structures */
1087 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1088 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1090 /* Marshall data and send request */
1092 q.ctr = ctr;
1094 init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1095 ctr->info.id);
1097 if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1098 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1099 goto done;
1102 /* Unmarshall response */
1104 if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1105 goto done;
1108 /* Return output parameters */
1110 if (!NT_STATUS_IS_OK(result = r.status)) {
1111 goto done;
1114 done:
1115 prs_mem_free(&qbuf);
1116 prs_mem_free(&rbuf);
1118 return result;
1121 /* Set userinfo2 */
1123 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1124 POLICY_HND *user_pol, uint16 switch_value,
1125 uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1127 prs_struct qbuf, rbuf;
1128 SAMR_Q_SET_USERINFO2 q;
1129 SAMR_R_SET_USERINFO2 r;
1130 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1132 ZERO_STRUCT(q);
1133 ZERO_STRUCT(r);
1135 /* Initialise parse structures */
1137 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1138 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1140 /* Marshall data and send request */
1142 init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1144 if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1145 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1146 goto done;
1149 /* Unmarshall response */
1151 if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1152 goto done;
1155 /* Return output parameters */
1157 if (!NT_STATUS_IS_OK(result = r.status)) {
1158 goto done;
1161 done:
1162 prs_mem_free(&qbuf);
1163 prs_mem_free(&rbuf);
1165 return result;
1168 /* Delete domain user */
1170 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1171 POLICY_HND *user_pol)
1173 prs_struct qbuf, rbuf;
1174 SAMR_Q_DELETE_DOM_USER q;
1175 SAMR_R_DELETE_DOM_USER r;
1176 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1178 ZERO_STRUCT(q);
1179 ZERO_STRUCT(r);
1181 /* Initialise parse structures */
1183 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1184 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1186 /* Marshall data and send request */
1188 init_samr_q_delete_dom_user(&q, user_pol);
1190 if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1191 !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1192 goto done;
1195 /* Unmarshall response */
1197 if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1198 goto done;
1201 /* Return output parameters */
1203 result = r.status;
1205 done:
1206 prs_mem_free(&qbuf);
1207 prs_mem_free(&rbuf);
1209 return result;
1212 /* Query user security object */
1214 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1215 POLICY_HND *user_pol, uint16 switch_value,
1216 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1218 prs_struct qbuf, rbuf;
1219 SAMR_Q_QUERY_SEC_OBJ q;
1220 SAMR_R_QUERY_SEC_OBJ r;
1221 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1223 ZERO_STRUCT(q);
1224 ZERO_STRUCT(r);
1226 /* Initialise parse structures */
1228 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1229 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1231 /* Marshall data and send request */
1233 init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1235 if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1236 !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1237 goto done;
1240 /* Unmarshall response */
1242 if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1243 goto done;
1246 /* Return output parameters */
1248 result = r.status;
1249 *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1251 done:
1252 prs_mem_free(&qbuf);
1253 prs_mem_free(&rbuf);
1255 return result;