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 rpccli_samr_connect(struct rpc_pipe_client *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->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->cli->desthost, access_mask);
52 if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53 !rpc_api_pipe_req_int(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 NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
78 uint32 access_mask, POLICY_HND *connect_pol)
80 return rpccli_samr_connect(&cli->pipes[PI_SAMR], mem_ctx,
81 access_mask, connect_pol);
83 /* Connect to SAMR database */
85 NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
86 uint32 access_mask, POLICY_HND *connect_pol)
88 prs_struct qbuf, rbuf;
91 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
93 DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
98 /* Initialise parse structures */
100 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
101 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
103 /* Marshall data and send request */
105 init_samr_q_connect4(&q, cli->desthost, access_mask);
107 if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
108 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
111 /* Unmarshall response */
113 if (!samr_io_r_connect4("", &r, &rbuf, 0))
116 /* Return output parameters */
118 if (NT_STATUS_IS_OK(result = r.status)) {
119 *connect_pol = r.connect_pol;
121 connect_pol->marker = malloc(1);
132 /* Close SAMR handle */
134 NTSTATUS rpccli_samr_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
135 POLICY_HND *connect_pol)
137 prs_struct qbuf, rbuf;
140 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
142 DEBUG(10,("cli_samr_close\n"));
147 /* Initialise parse structures */
149 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
150 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
152 /* Marshall data and send request */
154 init_samr_q_close_hnd(&q, connect_pol);
156 if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
157 !rpc_api_pipe_req_int(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
160 /* Unmarshall response */
162 if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
165 /* Return output parameters */
167 if (NT_STATUS_IS_OK(result = r.status)) {
169 SAFE_FREE(connect_pol->marker);
171 *connect_pol = r.pol;
181 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
182 POLICY_HND *connect_pol)
184 return rpccli_samr_close(&cli->pipes[PI_SAMR], mem_ctx, connect_pol);
187 /* Open handle on a domain */
189 NTSTATUS rpccli_samr_open_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
190 POLICY_HND *connect_pol, uint32 access_mask,
191 const DOM_SID *domain_sid,
192 POLICY_HND *domain_pol)
194 prs_struct qbuf, rbuf;
195 SAMR_Q_OPEN_DOMAIN q;
196 SAMR_R_OPEN_DOMAIN r;
197 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
199 DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
204 /* Initialise parse structures */
206 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
207 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
209 /* Marshall data and send request */
211 init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
213 if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
214 !rpc_api_pipe_req_int(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
217 /* Unmarshall response */
219 if (!samr_io_r_open_domain("", &r, &rbuf, 0))
222 /* Return output parameters */
224 if (NT_STATUS_IS_OK(result = r.status)) {
225 *domain_pol = r.domain_pol;
227 domain_pol->marker = malloc(1);
238 /* Open handle on a user */
240 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
241 POLICY_HND *connect_pol, uint32 access_mask,
242 const DOM_SID *domain_sid,
243 POLICY_HND *domain_pol)
245 return rpccli_samr_open_domain(&cli->pipes[PI_SAMR], mem_ctx,
246 connect_pol, access_mask, domain_sid,
251 NTSTATUS rpccli_samr_open_user(struct rpc_pipe_client *cli,
253 POLICY_HND *domain_pol, uint32 access_mask,
254 uint32 user_rid, POLICY_HND *user_pol)
256 prs_struct qbuf, rbuf;
259 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
261 DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
266 /* Initialise parse structures */
268 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
269 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
271 /* Marshall data and send request */
273 init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
275 if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
276 !rpc_api_pipe_req_int(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
279 /* Unmarshall response */
281 if (!samr_io_r_open_user("", &r, &rbuf, 0))
284 /* Return output parameters */
286 if (NT_STATUS_IS_OK(result = r.status)) {
287 *user_pol = r.user_pol;
289 user_pol->marker = malloc(1);
300 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
301 POLICY_HND *domain_pol, uint32 access_mask,
302 uint32 user_rid, POLICY_HND *user_pol)
304 return rpccli_samr_open_user(&cli->pipes[PI_SAMR], mem_ctx, domain_pol,
305 access_mask, user_rid, user_pol);
309 /* Open handle on a group */
311 NTSTATUS rpccli_samr_open_group(struct rpc_pipe_client *cli,
313 POLICY_HND *domain_pol, uint32 access_mask,
314 uint32 group_rid, POLICY_HND *group_pol)
316 prs_struct qbuf, rbuf;
319 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
321 DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
326 /* Initialise parse structures */
328 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
329 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
331 /* Marshall data and send request */
333 init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
335 if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
336 !rpc_api_pipe_req_int(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
339 /* Unmarshall response */
341 if (!samr_io_r_open_group("", &r, &rbuf, 0))
344 /* Return output parameters */
346 if (NT_STATUS_IS_OK(result = r.status)) {
349 group_pol->marker = malloc(1);
360 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
361 POLICY_HND *domain_pol, uint32 access_mask,
362 uint32 group_rid, POLICY_HND *group_pol)
364 return rpccli_samr_open_group(&cli->pipes[PI_SAMR], mem_ctx,
365 domain_pol, access_mask, group_rid,
369 /* Create domain group */
371 NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
372 POLICY_HND *domain_pol,
373 const char *group_name,
374 uint32 access_mask, POLICY_HND *group_pol)
376 prs_struct qbuf, rbuf;
377 SAMR_Q_CREATE_DOM_GROUP q;
378 SAMR_R_CREATE_DOM_GROUP r;
379 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
381 DEBUG(10,("cli_samr_create_dom_group\n"));
386 /* Initialise parse structures */
388 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
389 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
391 /* Marshall data and send request */
393 init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
395 if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
396 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
399 /* Unmarshall response */
401 if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
404 /* Return output parameters */
408 if (NT_STATUS_IS_OK(result))
418 /* Add a domain group member */
420 NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
421 POLICY_HND *group_pol, uint32 rid)
423 prs_struct qbuf, rbuf;
424 SAMR_Q_ADD_GROUPMEM q;
425 SAMR_R_ADD_GROUPMEM r;
426 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
428 DEBUG(10,("cli_samr_add_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_add_groupmem(&q, group_pol, rid);
442 if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
443 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
446 /* Unmarshall response */
448 if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
451 /* Return output parameters */
462 /* Delete a domain group member */
464 NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
465 POLICY_HND *group_pol, uint32 rid)
467 prs_struct qbuf, rbuf;
468 SAMR_Q_DEL_GROUPMEM q;
469 SAMR_R_DEL_GROUPMEM r;
470 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
472 DEBUG(10,("cli_samr_del_groupmem\n"));
477 /* Initialise parse structures */
479 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
480 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
482 /* Marshall data and send request */
484 init_samr_q_del_groupmem(&q, group_pol, rid);
486 if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
487 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
490 /* Unmarshall response */
492 if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
495 /* Return output parameters */
506 /* Query user info */
508 NTSTATUS rpccli_samr_query_userinfo(struct rpc_pipe_client *cli,
510 POLICY_HND *user_pol, uint16 switch_value,
511 SAM_USERINFO_CTR **ctr)
513 prs_struct qbuf, rbuf;
514 SAMR_Q_QUERY_USERINFO q;
515 SAMR_R_QUERY_USERINFO r;
516 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
518 DEBUG(10,("cli_samr_query_userinfo\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_query_userinfo(&q, user_pol, switch_value);
532 if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
533 !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
536 /* Unmarshall response */
538 if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
541 /* Return output parameters */
553 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
554 POLICY_HND *user_pol, uint16 switch_value,
555 SAM_USERINFO_CTR **ctr)
557 return rpccli_samr_query_userinfo(&cli->pipes[PI_SAMR], mem_ctx,
558 user_pol, switch_value, ctr);
563 NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
564 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
566 prs_struct qbuf, rbuf;
567 SAMR_Q_SET_GROUPINFO q;
568 SAMR_R_SET_GROUPINFO r;
569 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
571 DEBUG(10,("cli_samr_set_groupinfo\n"));
576 /* Initialise parse structures */
578 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
579 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
581 /* Marshall data and send request */
583 init_samr_q_set_groupinfo(&q, group_pol, ctr);
585 if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
586 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
589 /* Unmarshall response */
591 if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
594 /* Return output parameters */
605 /* Query group info */
607 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
608 POLICY_HND *group_pol, uint32 info_level,
609 GROUP_INFO_CTR **ctr)
611 prs_struct qbuf, rbuf;
612 SAMR_Q_QUERY_GROUPINFO q;
613 SAMR_R_QUERY_GROUPINFO r;
614 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
616 DEBUG(10,("cli_samr_query_groupinfo\n"));
621 /* Initialise parse structures */
623 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
624 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
626 /* Marshall data and send request */
628 init_samr_q_query_groupinfo(&q, group_pol, info_level);
630 if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
631 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
634 /* Unmarshall response */
636 if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
641 /* Return output parameters */
652 /* Query user groups */
654 NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
656 POLICY_HND *user_pol,
660 prs_struct qbuf, rbuf;
661 SAMR_Q_QUERY_USERGROUPS q;
662 SAMR_R_QUERY_USERGROUPS r;
663 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
665 DEBUG(10,("cli_samr_query_usergroups\n"));
670 /* Initialise parse structures */
672 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
673 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
675 /* Marshall data and send request */
677 init_samr_q_query_usergroups(&q, user_pol);
679 if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
680 !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
683 /* Unmarshall response */
685 if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
688 /* Return output parameters */
690 if (NT_STATUS_IS_OK(result = r.status)) {
691 *num_groups = r.num_entries;
702 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
703 POLICY_HND *user_pol, uint32 *num_groups,
706 return rpccli_samr_query_usergroups(&cli->pipes[PI_SAMR], mem_ctx,
707 user_pol, num_groups, gid);
712 NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
713 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
715 prs_struct qbuf, rbuf;
716 SAMR_Q_SET_ALIASINFO q;
717 SAMR_R_SET_ALIASINFO r;
718 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
720 DEBUG(10,("cli_samr_set_aliasinfo\n"));
725 /* Initialise parse structures */
727 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
728 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
730 /* Marshall data and send request */
732 init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
734 if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
735 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
738 /* Unmarshall response */
740 if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
743 /* Return output parameters */
754 /* Query user aliases */
756 NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
758 POLICY_HND *dom_pol, uint32 num_sids,
760 uint32 *num_aliases, uint32 **als_rids)
762 prs_struct qbuf, rbuf;
763 SAMR_Q_QUERY_USERALIASES q;
764 SAMR_R_QUERY_USERALIASES r;
765 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
769 DEBUG(10,("cli_samr_query_useraliases\n"));
774 /* Initialise parse structures */
776 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
777 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
779 sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
780 if (sid_ptrs == NULL)
781 return NT_STATUS_NO_MEMORY;
783 for (i=0; i<num_sids; i++)
786 /* Marshall data and send request */
788 init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
790 if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
791 !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
794 /* Unmarshall response */
796 if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
799 /* Return output parameters */
801 if (NT_STATUS_IS_OK(result = r.status)) {
802 *num_aliases = r.num_entries;
813 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli,
815 POLICY_HND *dom_pol, uint32 num_sids,
817 uint32 *num_aliases, uint32 **als_rids)
819 return rpccli_samr_query_useraliases(&cli->pipes[PI_SAMR], mem_ctx,
820 dom_pol, num_sids, sid,
821 num_aliases, als_rids);
825 /* Query user groups */
827 NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
829 POLICY_HND *group_pol, uint32 *num_mem,
830 uint32 **rid, uint32 **attr)
832 prs_struct qbuf, rbuf;
833 SAMR_Q_QUERY_GROUPMEM q;
834 SAMR_R_QUERY_GROUPMEM r;
835 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
837 DEBUG(10,("cli_samr_query_groupmem\n"));
842 /* Initialise parse structures */
844 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
845 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
847 /* Marshall data and send request */
849 init_samr_q_query_groupmem(&q, group_pol);
851 if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
852 !rpc_api_pipe_req_int(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
855 /* Unmarshall response */
857 if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
860 /* Return output parameters */
862 if (NT_STATUS_IS_OK(result = r.status)) {
863 *num_mem = r.num_entries;
875 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
876 POLICY_HND *group_pol, uint32 *num_mem,
877 uint32 **rid, uint32 **attr)
879 return rpccli_samr_query_groupmem(&cli->pipes[PI_SAMR], mem_ctx,
880 group_pol, num_mem, rid, attr);
885 * Enumerate domain users
887 * @param cli client state structure
888 * @param mem_ctx talloc context
889 * @param pol opened domain policy handle
890 * @param start_idx starting index of enumeration, returns context for
892 * @param acb_mask account control bit mask (to enumerate some particular
894 * @param size max acceptable size of response
895 * @param dom_users returned array of domain user names
896 * @param rids returned array of domain user RIDs
897 * @param num_dom_users numer returned entries
899 * @return NTSTATUS returned in rpc response
901 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
902 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
903 uint32 size, char ***dom_users, uint32 **rids,
904 uint32 *num_dom_users)
908 SAMR_Q_ENUM_DOM_USERS q;
909 SAMR_R_ENUM_DOM_USERS r;
910 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
913 DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
918 /* always init this */
921 /* Initialise parse structures */
923 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
924 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
926 /* Fill query structure with parameters */
928 init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
930 if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
931 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
935 /* unpack received stream */
937 if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
942 if (!NT_STATUS_IS_OK(result) &&
943 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
946 *start_idx = r.next_idx;
947 *num_dom_users = r.num_entries2;
949 if (r.num_entries2) {
950 /* allocate memory needed to return received data */
951 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
953 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
954 return NT_STATUS_NO_MEMORY;
957 *dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
959 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
960 return NT_STATUS_NO_MEMORY;
963 /* fill output buffers with rpc response */
964 for (i = 0; i < r.num_entries2; i++) {
967 (*rids)[i] = r.sam[i].rid;
968 unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
969 (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
980 /* Enumerate domain groups */
982 NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
984 POLICY_HND *pol, uint32 *start_idx,
985 uint32 size, struct acct_info **dom_groups,
986 uint32 *num_dom_groups)
988 prs_struct qbuf, rbuf;
989 SAMR_Q_ENUM_DOM_GROUPS q;
990 SAMR_R_ENUM_DOM_GROUPS r;
991 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
994 DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
999 /* Initialise parse structures */
1001 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1002 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1004 /* Marshall data and send request */
1006 init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
1008 if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
1009 !rpc_api_pipe_req_int(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
1012 /* Unmarshall response */
1014 if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
1017 /* Return output parameters */
1021 if (!NT_STATUS_IS_OK(result) &&
1022 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
1025 *num_dom_groups = r.num_entries2;
1027 if (*num_dom_groups == 0)
1030 if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
1031 result = NT_STATUS_NO_MEMORY;
1035 memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
1039 for (i = 0; i < *num_dom_groups; i++) {
1041 (*dom_groups)[i].rid = r.sam[i].rid;
1043 if (r.sam[i].hdr_name.buffer) {
1044 unistr2_to_ascii((*dom_groups)[i].acct_name,
1045 &r.uni_grp_name[name_idx],
1046 sizeof(fstring) - 1);
1050 *start_idx = r.next_idx;
1054 prs_mem_free(&qbuf);
1055 prs_mem_free(&rbuf);
1060 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1061 POLICY_HND *pol, uint32 *start_idx,
1062 uint32 size, struct acct_info **dom_groups,
1063 uint32 *num_dom_groups)
1065 return rpccli_samr_enum_dom_groups(&cli->pipes[PI_SAMR], mem_ctx,
1066 pol, start_idx, size, dom_groups,
1070 /* Enumerate domain groups */
1072 NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
1073 TALLOC_CTX *mem_ctx,
1074 POLICY_HND *pol, uint32 *start_idx,
1075 uint32 size, struct acct_info **dom_aliases,
1076 uint32 *num_dom_aliases)
1078 prs_struct qbuf, rbuf;
1079 SAMR_Q_ENUM_DOM_ALIASES q;
1080 SAMR_R_ENUM_DOM_ALIASES r;
1081 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1084 DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
1089 /* Initialise parse structures */
1091 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1092 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1094 /* Marshall data and send request */
1096 init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
1098 if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
1099 !rpc_api_pipe_req_int(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
1103 /* Unmarshall response */
1105 if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1109 /* Return output parameters */
1113 if (!NT_STATUS_IS_OK(result) &&
1114 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1118 *num_dom_aliases = r.num_entries2;
1120 if (*num_dom_aliases == 0)
1123 if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
1124 result = NT_STATUS_NO_MEMORY;
1128 memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1132 for (i = 0; i < *num_dom_aliases; i++) {
1134 (*dom_aliases)[i].rid = r.sam[i].rid;
1136 if (r.sam[i].hdr_name.buffer) {
1137 unistr2_to_ascii((*dom_aliases)[i].acct_name,
1138 &r.uni_grp_name[name_idx],
1139 sizeof(fstring) - 1);
1143 *start_idx = r.next_idx;
1147 prs_mem_free(&qbuf);
1148 prs_mem_free(&rbuf);
1153 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1154 POLICY_HND *pol, uint32 *start_idx,
1155 uint32 size, struct acct_info **dom_aliases,
1156 uint32 *num_dom_aliases)
1158 return rpccli_samr_enum_als_groups(&cli->pipes[PI_SAMR], mem_ctx,
1159 pol, start_idx, size, dom_aliases,
1163 /* Query alias members */
1165 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1166 POLICY_HND *alias_pol, uint32 *num_mem,
1169 prs_struct qbuf, rbuf;
1170 SAMR_Q_QUERY_ALIASMEM q;
1171 SAMR_R_QUERY_ALIASMEM r;
1172 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1175 DEBUG(10,("cli_samr_query_aliasmem\n"));
1180 /* Initialise parse structures */
1182 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1183 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1185 /* Marshall data and send request */
1187 init_samr_q_query_aliasmem(&q, alias_pol);
1189 if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1190 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1194 /* Unmarshall response */
1196 if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1200 /* Return output parameters */
1202 if (!NT_STATUS_IS_OK(result = r.status)) {
1206 *num_mem = r.num_sids;
1208 if (*num_mem == 0) {
1210 result = NT_STATUS_OK;
1214 if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
1215 result = NT_STATUS_UNSUCCESSFUL;
1219 for (i = 0; i < *num_mem; i++) {
1220 (*sids)[i] = r.sid[i].sid;
1224 prs_mem_free(&qbuf);
1225 prs_mem_free(&rbuf);
1230 /* Open handle on an alias */
1232 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1233 POLICY_HND *domain_pol, uint32 access_mask,
1234 uint32 alias_rid, POLICY_HND *alias_pol)
1236 prs_struct qbuf, rbuf;
1237 SAMR_Q_OPEN_ALIAS q;
1238 SAMR_R_OPEN_ALIAS r;
1241 DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1246 /* Initialise parse structures */
1248 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1249 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1251 /* Marshall data and send request */
1253 init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1255 if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1256 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1257 result = NT_STATUS_UNSUCCESSFUL;
1261 /* Unmarshall response */
1263 if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1264 result = NT_STATUS_UNSUCCESSFUL;
1268 /* Return output parameters */
1270 if (NT_STATUS_IS_OK(result = r.status)) {
1273 alias_pol->marker = malloc(1);
1278 prs_mem_free(&qbuf);
1279 prs_mem_free(&rbuf);
1284 /* Create an alias */
1286 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1287 POLICY_HND *domain_pol, const char *name,
1288 POLICY_HND *alias_pol)
1290 prs_struct qbuf, rbuf;
1291 SAMR_Q_CREATE_DOM_ALIAS q;
1292 SAMR_R_CREATE_DOM_ALIAS r;
1295 DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1300 /* Initialise parse structures */
1302 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1303 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1305 /* Marshall data and send request */
1307 init_samr_q_create_dom_alias(&q, domain_pol, name);
1309 if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1310 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1311 result = NT_STATUS_UNSUCCESSFUL;
1315 /* Unmarshall response */
1317 if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1318 result = NT_STATUS_UNSUCCESSFUL;
1322 /* Return output parameters */
1324 if (NT_STATUS_IS_OK(result = r.status)) {
1325 *alias_pol = r.alias_pol;
1329 prs_mem_free(&qbuf);
1330 prs_mem_free(&rbuf);
1335 /* Add an alias member */
1337 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1338 POLICY_HND *alias_pol, DOM_SID *member)
1340 prs_struct qbuf, rbuf;
1341 SAMR_Q_ADD_ALIASMEM q;
1342 SAMR_R_ADD_ALIASMEM r;
1345 DEBUG(10,("cli_samr_add_aliasmem"));
1350 /* Initialise parse structures */
1352 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1353 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1355 /* Marshall data and send request */
1357 init_samr_q_add_aliasmem(&q, alias_pol, member);
1359 if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1360 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1361 result = NT_STATUS_UNSUCCESSFUL;
1365 /* Unmarshall response */
1367 if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1368 result = NT_STATUS_UNSUCCESSFUL;
1375 prs_mem_free(&qbuf);
1376 prs_mem_free(&rbuf);
1381 /* Delete an alias member */
1383 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1384 POLICY_HND *alias_pol, DOM_SID *member)
1386 prs_struct qbuf, rbuf;
1387 SAMR_Q_DEL_ALIASMEM q;
1388 SAMR_R_DEL_ALIASMEM r;
1391 DEBUG(10,("cli_samr_del_aliasmem"));
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_del_aliasmem(&q, alias_pol, member);
1405 if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1406 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1407 result = NT_STATUS_UNSUCCESSFUL;
1411 /* Unmarshall response */
1413 if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1414 result = NT_STATUS_UNSUCCESSFUL;
1421 prs_mem_free(&qbuf);
1422 prs_mem_free(&rbuf);
1427 /* Query alias info */
1429 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1430 POLICY_HND *alias_pol, uint16 switch_value,
1431 ALIAS_INFO_CTR *ctr)
1433 prs_struct qbuf, rbuf;
1434 SAMR_Q_QUERY_ALIASINFO q;
1435 SAMR_R_QUERY_ALIASINFO r;
1436 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1438 DEBUG(10,("cli_samr_query_alias_info\n"));
1443 /* Initialise parse structures */
1445 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1446 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1448 /* Marshall data and send request */
1450 init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1452 if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1453 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1457 /* Unmarshall response */
1459 if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1463 /* Return output parameters */
1465 if (!NT_STATUS_IS_OK(result = r.status)) {
1472 prs_mem_free(&qbuf);
1473 prs_mem_free(&rbuf);
1478 /* Query domain info */
1480 NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
1481 TALLOC_CTX *mem_ctx,
1482 POLICY_HND *domain_pol,
1483 uint16 switch_value,
1486 prs_struct qbuf, rbuf;
1487 SAMR_Q_QUERY_DOMAIN_INFO q;
1488 SAMR_R_QUERY_DOMAIN_INFO r;
1489 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1491 DEBUG(10,("cli_samr_query_dom_info\n"));
1496 /* Initialise parse structures */
1498 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1499 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1501 /* Marshall data and send request */
1503 init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1505 if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1506 !rpc_api_pipe_req_int(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1510 /* Unmarshall response */
1514 if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1518 /* Return output parameters */
1520 if (!NT_STATUS_IS_OK(result = r.status)) {
1525 prs_mem_free(&qbuf);
1526 prs_mem_free(&rbuf);
1531 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1532 POLICY_HND *domain_pol, uint16 switch_value,
1535 return rpccli_samr_query_dom_info(&cli->pipes[PI_SAMR], mem_ctx,
1536 domain_pol, switch_value, ctr);
1539 /* User change password */
1541 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
1542 TALLOC_CTX *mem_ctx,
1543 const char *username,
1544 const char *newpassword,
1545 const char *oldpassword )
1547 prs_struct qbuf, rbuf;
1548 SAMR_Q_CHGPASSWD_USER q;
1549 SAMR_R_CHGPASSWD_USER r;
1550 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1552 uchar new_nt_password[516];
1553 uchar new_lm_password[516];
1554 uchar old_nt_hash[16];
1555 uchar old_lanman_hash[16];
1556 uchar old_nt_hash_enc[16];
1557 uchar old_lanman_hash_enc[16];
1559 uchar new_nt_hash[16];
1560 uchar new_lanman_hash[16];
1562 DEBUG(10,("cli_samr_query_dom_info\n"));
1567 /* Calculate the MD4 hash (NT compatible) of the password */
1568 E_md4hash(oldpassword, old_nt_hash);
1569 E_md4hash(newpassword, new_nt_hash);
1571 if (lp_client_lanman_auth()
1572 && E_deshash(newpassword, new_lanman_hash)
1573 && E_deshash(oldpassword, old_lanman_hash)) {
1574 /* E_deshash returns false for 'long' passwords (> 14
1575 DOS chars). This allows us to match Win2k, which
1576 does not store a LM hash for these passwords (which
1577 would reduce the effective password length to 14) */
1579 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1581 SamOEMhash( new_lm_password, old_nt_hash, 516);
1582 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1584 ZERO_STRUCT(new_lm_password);
1585 ZERO_STRUCT(old_lanman_hash_enc);
1588 encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1590 SamOEMhash( new_nt_password, old_nt_hash, 516);
1591 E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1593 /* Initialise parse structures */
1595 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1596 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1598 /* Marshall data and send request */
1600 init_samr_q_chgpasswd_user(&q, cli->cli->srv_name_slash, username,
1604 old_lanman_hash_enc);
1606 if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1607 !rpc_api_pipe_req_int(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1611 /* Unmarshall response */
1613 if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1617 /* Return output parameters */
1619 if (!NT_STATUS_IS_OK(result = r.status)) {
1624 prs_mem_free(&qbuf);
1625 prs_mem_free(&rbuf);
1630 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1631 const char *username,
1632 const char *newpassword,
1633 const char *oldpassword )
1635 return rpccli_samr_chgpasswd_user(&cli->pipes[PI_SAMR], mem_ctx,
1636 username, newpassword, oldpassword);
1639 /* This function returns the bizzare set of (max_entries, max_size) required
1640 for the QueryDisplayInfo RPC to actually work against a domain controller
1641 with large (10k and higher) numbers of users. These values were
1642 obtained by inspection using ethereal and NT4 running User Manager. */
1644 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1647 switch(loop_count) {
1653 *max_entries = 1024;
1657 *max_entries = 2048;
1661 *max_entries = 4096;
1664 default: /* loop_count >= 4 */
1665 *max_entries = 4096;
1671 /* Query display info */
1673 NTSTATUS rpccli_samr_query_dispinfo(struct rpc_pipe_client *cli,
1674 TALLOC_CTX *mem_ctx,
1675 POLICY_HND *domain_pol, uint32 *start_idx,
1676 uint16 switch_value, uint32 *num_entries,
1677 uint32 max_entries, uint32 max_size,
1678 SAM_DISPINFO_CTR *ctr)
1680 prs_struct qbuf, rbuf;
1681 SAMR_Q_QUERY_DISPINFO q;
1682 SAMR_R_QUERY_DISPINFO r;
1683 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1685 DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1692 /* Initialise parse structures */
1694 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1695 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1697 /* Marshall data and send request */
1699 init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1700 *start_idx, max_entries, max_size);
1702 if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1703 !rpc_api_pipe_req_int(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1707 /* Unmarshall response */
1711 if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1715 /* Return output parameters */
1719 if (!NT_STATUS_IS_OK(result) &&
1720 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1724 *num_entries = r.num_entries;
1725 *start_idx += r.num_entries; /* No next_idx in this structure! */
1728 prs_mem_free(&qbuf);
1729 prs_mem_free(&rbuf);
1734 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1735 POLICY_HND *domain_pol, uint32 *start_idx,
1736 uint16 switch_value, uint32 *num_entries,
1737 uint32 max_entries, uint32 max_size,
1738 SAM_DISPINFO_CTR *ctr)
1740 return rpccli_samr_query_dispinfo(&cli->pipes[PI_SAMR], mem_ctx,
1741 domain_pol, start_idx, switch_value,
1742 num_entries, max_entries, max_size, ctr);
1745 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
1746 looked up in one packet. */
1748 NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
1749 TALLOC_CTX *mem_ctx,
1750 POLICY_HND *domain_pol,
1751 uint32 num_rids, uint32 *rids,
1752 uint32 *num_names, char ***names,
1753 uint32 **name_types)
1755 prs_struct qbuf, rbuf;
1756 SAMR_Q_LOOKUP_RIDS q;
1757 SAMR_R_LOOKUP_RIDS r;
1758 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1761 DEBUG(10,("cli_samr_lookup_rids\n"));
1763 if (num_rids > 1000) {
1764 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1765 "more than ~1000 rids are looked up at once.\n"));
1771 /* Initialise parse structures */
1773 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1774 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1776 /* Marshall data and send request */
1778 init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
1780 if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1781 !rpc_api_pipe_req_int(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1785 /* Unmarshall response */
1787 if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1791 /* Return output parameters */
1795 if (!NT_STATUS_IS_OK(result) &&
1796 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1799 if (r.num_names1 == 0) {
1805 *num_names = r.num_names1;
1806 *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1807 *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1809 for (i = 0; i < r.num_names1; i++) {
1812 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1813 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1814 (*name_types)[i] = r.type[i];
1818 prs_mem_free(&qbuf);
1819 prs_mem_free(&rbuf);
1824 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1825 POLICY_HND *domain_pol,
1826 uint32 num_rids, uint32 *rids,
1827 uint32 *num_names, char ***names,
1828 uint32 **name_types)
1830 return rpccli_samr_lookup_rids(&cli->pipes[PI_SAMR], mem_ctx,
1831 domain_pol, num_rids, rids,
1832 num_names, names, name_types);
1837 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1838 POLICY_HND *domain_pol, uint32 flags,
1839 uint32 num_names, const char **names,
1840 uint32 *num_rids, uint32 **rids,
1843 prs_struct qbuf, rbuf;
1844 SAMR_Q_LOOKUP_NAMES q;
1845 SAMR_R_LOOKUP_NAMES r;
1846 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1849 DEBUG(10,("cli_samr_lookup_names\n"));
1854 /* Initialise parse structures */
1856 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1857 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1859 /* Marshall data and send request */
1861 init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1864 if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1865 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1869 /* Unmarshall response */
1871 if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1875 /* Return output parameters */
1877 if (!NT_STATUS_IS_OK(result = r.status)) {
1881 if (r.num_rids1 == 0) {
1886 *num_rids = r.num_rids1;
1887 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1888 *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1890 for (i = 0; i < r.num_rids1; i++) {
1891 (*rids)[i] = r.rids[i];
1892 (*rid_types)[i] = r.types[i];
1896 prs_mem_free(&qbuf);
1897 prs_mem_free(&rbuf);
1902 /* Create a domain user */
1904 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1905 POLICY_HND *domain_pol, const char *acct_name,
1906 uint32 acb_info, uint32 unknown,
1907 POLICY_HND *user_pol, uint32 *rid)
1909 prs_struct qbuf, rbuf;
1910 SAMR_Q_CREATE_USER q;
1911 SAMR_R_CREATE_USER r;
1912 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1914 DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1919 /* Initialise parse structures */
1921 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1922 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1924 /* Marshall data and send request */
1926 init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1928 if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1929 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1933 /* Unmarshall response */
1935 if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1939 /* Return output parameters */
1941 if (!NT_STATUS_IS_OK(result = r.status)) {
1946 *user_pol = r.user_pol;
1952 prs_mem_free(&qbuf);
1953 prs_mem_free(&rbuf);
1960 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1961 POLICY_HND *user_pol, uint16 switch_value,
1962 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1964 prs_struct qbuf, rbuf;
1965 SAMR_Q_SET_USERINFO q;
1966 SAMR_R_SET_USERINFO r;
1967 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1969 DEBUG(10,("cli_samr_set_userinfo\n"));
1974 if (!sess_key->length) {
1975 DEBUG(1, ("No user session key\n"));
1976 return NT_STATUS_NO_USER_SESSION_KEY;
1979 /* Initialise parse structures */
1981 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1982 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1984 /* Marshall data and send request */
1988 init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1991 if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1992 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1996 /* Unmarshall response */
1998 if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
2002 /* Return output parameters */
2004 if (!NT_STATUS_IS_OK(result = r.status)) {
2009 prs_mem_free(&qbuf);
2010 prs_mem_free(&rbuf);
2017 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2018 POLICY_HND *user_pol, uint16 switch_value,
2019 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
2021 prs_struct qbuf, rbuf;
2022 SAMR_Q_SET_USERINFO2 q;
2023 SAMR_R_SET_USERINFO2 r;
2024 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2026 DEBUG(10,("cli_samr_set_userinfo2\n"));
2028 if (!sess_key->length) {
2029 DEBUG(1, ("No user session key\n"));
2030 return NT_STATUS_NO_USER_SESSION_KEY;
2036 /* Initialise parse structures */
2038 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2039 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2041 /* Marshall data and send request */
2043 init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
2045 if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
2046 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
2050 /* Unmarshall response */
2052 if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
2056 /* Return output parameters */
2058 if (!NT_STATUS_IS_OK(result = r.status)) {
2063 prs_mem_free(&qbuf);
2064 prs_mem_free(&rbuf);
2069 /* Delete domain group */
2071 NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2072 POLICY_HND *group_pol)
2074 prs_struct qbuf, rbuf;
2075 SAMR_Q_DELETE_DOM_GROUP q;
2076 SAMR_R_DELETE_DOM_GROUP r;
2077 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2079 DEBUG(10,("cli_samr_delete_dom_group\n"));
2084 /* Initialise parse structures */
2086 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2087 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2089 /* Marshall data and send request */
2091 init_samr_q_delete_dom_group(&q, group_pol);
2093 if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
2094 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
2098 /* Unmarshall response */
2100 if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
2104 /* Return output parameters */
2109 prs_mem_free(&qbuf);
2110 prs_mem_free(&rbuf);
2115 /* Delete domain alias */
2117 NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2118 POLICY_HND *alias_pol)
2120 prs_struct qbuf, rbuf;
2121 SAMR_Q_DELETE_DOM_ALIAS q;
2122 SAMR_R_DELETE_DOM_ALIAS r;
2123 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2125 DEBUG(10,("cli_samr_delete_dom_alias\n"));
2130 /* Initialise parse structures */
2132 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2133 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2135 /* Marshall data and send request */
2137 init_samr_q_delete_dom_alias(&q, alias_pol);
2139 if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
2140 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
2144 /* Unmarshall response */
2146 if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
2150 /* Return output parameters */
2155 prs_mem_free(&qbuf);
2156 prs_mem_free(&rbuf);
2161 /* Delete domain user */
2163 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2164 POLICY_HND *user_pol)
2166 prs_struct qbuf, rbuf;
2167 SAMR_Q_DELETE_DOM_USER q;
2168 SAMR_R_DELETE_DOM_USER r;
2169 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2171 DEBUG(10,("cli_samr_delete_dom_user\n"));
2176 /* Initialise parse structures */
2178 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2179 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2181 /* Marshall data and send request */
2183 init_samr_q_delete_dom_user(&q, user_pol);
2185 if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
2186 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
2190 /* Unmarshall response */
2192 if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
2196 /* Return output parameters */
2201 prs_mem_free(&qbuf);
2202 prs_mem_free(&rbuf);
2207 /* Remove foreign SID */
2209 NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli,
2210 TALLOC_CTX *mem_ctx,
2211 POLICY_HND *user_pol,
2214 prs_struct qbuf, rbuf;
2215 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
2216 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
2217 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2219 DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
2224 /* Initialise parse structures */
2226 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2227 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2229 /* Marshall data and send request */
2231 init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
2233 if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
2234 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
2238 /* Unmarshall response */
2240 if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
2244 /* Return output parameters */
2249 prs_mem_free(&qbuf);
2250 prs_mem_free(&rbuf);
2255 /* Query user security object */
2257 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2258 POLICY_HND *user_pol, uint16 switch_value,
2259 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
2261 prs_struct qbuf, rbuf;
2262 SAMR_Q_QUERY_SEC_OBJ q;
2263 SAMR_R_QUERY_SEC_OBJ r;
2264 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2266 DEBUG(10,("cli_samr_query_sec_obj\n"));
2271 /* Initialise parse structures */
2273 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2274 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2276 /* Marshall data and send request */
2278 init_samr_q_query_sec_obj(&q, user_pol, switch_value);
2280 if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
2281 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
2285 /* Unmarshall response */
2287 if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
2291 /* Return output parameters */
2294 *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
2297 prs_mem_free(&qbuf);
2298 prs_mem_free(&rbuf);
2303 /* Get domain password info */
2305 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2306 uint16 *unk_0, uint16 *unk_1)
2308 prs_struct qbuf, rbuf;
2309 SAMR_Q_GET_DOM_PWINFO q;
2310 SAMR_R_GET_DOM_PWINFO r;
2311 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2313 DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2318 /* Initialise parse structures */
2320 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2321 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2323 /* Marshall data and send request */
2325 init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2327 if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2328 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2331 /* Unmarshall response */
2333 if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2336 /* Return output parameters */
2340 if (NT_STATUS_IS_OK(result)) {
2348 prs_mem_free(&qbuf);
2349 prs_mem_free(&rbuf);
2354 /* Lookup Domain Name */
2356 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2357 POLICY_HND *user_pol, char *domain_name,
2360 prs_struct qbuf, rbuf;
2361 SAMR_Q_LOOKUP_DOMAIN q;
2362 SAMR_R_LOOKUP_DOMAIN r;
2363 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2365 DEBUG(10,("cli_samr_lookup_domain\n"));
2370 /* Initialise parse structures */
2372 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2373 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2375 /* Marshall data and send request */
2377 init_samr_q_lookup_domain(&q, user_pol, domain_name);
2379 if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2380 !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2383 /* Unmarshall response */
2385 if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2388 /* Return output parameters */
2392 if (NT_STATUS_IS_OK(result))
2393 sid_copy(sid, &r.dom_sid.sid);
2396 prs_mem_free(&qbuf);
2397 prs_mem_free(&rbuf);