Enable checking/resetting of account lockout and bad password based on policy
[Samba/gebeck_regimport.git] / source / rpc_client / cli_samr.c
blob38d2119e8385127ae176ced281899b05b8fd91c8
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,
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.
26 #include "includes.h"
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;
34 SAMR_Q_CONNECT q;
35 SAMR_R_CONNECT r;
36 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
38 DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
40 ZERO_STRUCT(q);
41 ZERO_STRUCT(r);
43 /* Initialise parse structures */
45 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
46 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
48 /* Marshall data and send request */
50 init_samr_q_connect(&q, cli->desthost, access_mask);
52 if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53 !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf))
54 goto done;
56 /* Unmarshall response */
58 if (!samr_io_r_connect("", &r, &rbuf, 0))
59 goto done;
61 /* Return output parameters */
63 if (NT_STATUS_IS_OK(result = r.status)) {
64 *connect_pol = r.connect_pol;
65 #ifdef __INSURE__
66 connect_pol->marker = malloc(1);
67 #endif
70 done:
71 prs_mem_free(&qbuf);
72 prs_mem_free(&rbuf);
74 return result;
77 /* Connect to SAMR database */
79 NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
80 uint32 access_mask, POLICY_HND *connect_pol)
82 prs_struct qbuf, rbuf;
83 SAMR_Q_CONNECT4 q;
84 SAMR_R_CONNECT4 r;
85 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
87 DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
89 ZERO_STRUCT(q);
90 ZERO_STRUCT(r);
92 /* Initialise parse structures */
94 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
95 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
97 /* Marshall data and send request */
99 init_samr_q_connect4(&q, cli->desthost, access_mask);
101 if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
102 !rpc_api_pipe_req(cli, SAMR_CONNECT4, &qbuf, &rbuf))
103 goto done;
105 /* Unmarshall response */
107 if (!samr_io_r_connect4("", &r, &rbuf, 0))
108 goto done;
110 /* Return output parameters */
112 if (NT_STATUS_IS_OK(result = r.status)) {
113 *connect_pol = r.connect_pol;
114 #ifdef __INSURE__
115 connect_pol->marker = malloc(1);
116 #endif
119 done:
120 prs_mem_free(&qbuf);
121 prs_mem_free(&rbuf);
123 return result;
126 /* Close SAMR handle */
128 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
129 POLICY_HND *connect_pol)
131 prs_struct qbuf, rbuf;
132 SAMR_Q_CLOSE_HND q;
133 SAMR_R_CLOSE_HND r;
134 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
136 DEBUG(10,("cli_samr_close\n"));
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_close_hnd(&q, connect_pol);
150 if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
151 !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
152 goto done;
154 /* Unmarshall response */
156 if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
157 goto done;
159 /* Return output parameters */
161 if (NT_STATUS_IS_OK(result = r.status)) {
162 #ifdef __INSURE__
163 SAFE_FREE(connect_pol->marker);
164 #endif
165 *connect_pol = r.pol;
168 done:
169 prs_mem_free(&qbuf);
170 prs_mem_free(&rbuf);
172 return result;
175 /* Open handle on a domain */
177 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
178 POLICY_HND *connect_pol, uint32 access_mask,
179 const DOM_SID *domain_sid, POLICY_HND *domain_pol)
181 prs_struct qbuf, rbuf;
182 SAMR_Q_OPEN_DOMAIN q;
183 SAMR_R_OPEN_DOMAIN r;
184 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
186 DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
188 ZERO_STRUCT(q);
189 ZERO_STRUCT(r);
191 /* Initialise parse structures */
193 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
194 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
196 /* Marshall data and send request */
198 init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
200 if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
201 !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
202 goto done;
204 /* Unmarshall response */
206 if (!samr_io_r_open_domain("", &r, &rbuf, 0))
207 goto done;
209 /* Return output parameters */
211 if (NT_STATUS_IS_OK(result = r.status)) {
212 *domain_pol = r.domain_pol;
213 #ifdef __INSURE__
214 domain_pol->marker = malloc(1);
215 #endif
218 done:
219 prs_mem_free(&qbuf);
220 prs_mem_free(&rbuf);
222 return result;
225 /* Open handle on a user */
227 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
228 POLICY_HND *domain_pol, uint32 access_mask,
229 uint32 user_rid, POLICY_HND *user_pol)
231 prs_struct qbuf, rbuf;
232 SAMR_Q_OPEN_USER q;
233 SAMR_R_OPEN_USER r;
234 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
236 DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
238 ZERO_STRUCT(q);
239 ZERO_STRUCT(r);
241 /* Initialise parse structures */
243 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
244 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
246 /* Marshall data and send request */
248 init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
250 if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
251 !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
252 goto done;
254 /* Unmarshall response */
256 if (!samr_io_r_open_user("", &r, &rbuf, 0))
257 goto done;
259 /* Return output parameters */
261 if (NT_STATUS_IS_OK(result = r.status)) {
262 *user_pol = r.user_pol;
263 #ifdef __INSURE__
264 user_pol->marker = malloc(1);
265 #endif
268 done:
269 prs_mem_free(&qbuf);
270 prs_mem_free(&rbuf);
272 return result;
275 /* Open handle on a group */
277 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
278 POLICY_HND *domain_pol, uint32 access_mask,
279 uint32 group_rid, POLICY_HND *group_pol)
281 prs_struct qbuf, rbuf;
282 SAMR_Q_OPEN_GROUP q;
283 SAMR_R_OPEN_GROUP r;
284 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
286 DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
288 ZERO_STRUCT(q);
289 ZERO_STRUCT(r);
291 /* Initialise parse structures */
293 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
294 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
296 /* Marshall data and send request */
298 init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
300 if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
301 !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
302 goto done;
304 /* Unmarshall response */
306 if (!samr_io_r_open_group("", &r, &rbuf, 0))
307 goto done;
309 /* Return output parameters */
311 if (NT_STATUS_IS_OK(result = r.status)) {
312 *group_pol = r.pol;
313 #ifdef __INSURE__
314 group_pol->marker = malloc(1);
315 #endif
318 done:
319 prs_mem_free(&qbuf);
320 prs_mem_free(&rbuf);
322 return result;
325 /* Query user info */
327 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
328 POLICY_HND *user_pol, uint16 switch_value,
329 SAM_USERINFO_CTR **ctr)
331 prs_struct qbuf, rbuf;
332 SAMR_Q_QUERY_USERINFO q;
333 SAMR_R_QUERY_USERINFO r;
334 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
336 DEBUG(10,("cli_samr_query_userinfo\n"));
338 ZERO_STRUCT(q);
339 ZERO_STRUCT(r);
341 /* Initialise parse structures */
343 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
344 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
346 /* Marshall data and send request */
348 init_samr_q_query_userinfo(&q, user_pol, switch_value);
350 if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
351 !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
352 goto done;
354 /* Unmarshall response */
356 if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
357 goto done;
359 /* Return output parameters */
361 result = r.status;
362 *ctr = r.ctr;
364 done:
365 prs_mem_free(&qbuf);
366 prs_mem_free(&rbuf);
368 return result;
371 /* Query group info */
373 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
374 POLICY_HND *group_pol, uint32 info_level,
375 GROUP_INFO_CTR **ctr)
377 prs_struct qbuf, rbuf;
378 SAMR_Q_QUERY_GROUPINFO q;
379 SAMR_R_QUERY_GROUPINFO r;
380 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
382 DEBUG(10,("cli_samr_query_groupinfo\n"));
384 ZERO_STRUCT(q);
385 ZERO_STRUCT(r);
387 /* Initialise parse structures */
389 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
390 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
392 /* Marshall data and send request */
394 init_samr_q_query_groupinfo(&q, group_pol, info_level);
396 if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
397 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
398 goto done;
400 /* Unmarshall response */
402 if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
403 goto done;
405 *ctr = r.ctr;
407 /* Return output parameters */
409 result = r.status;
411 done:
412 prs_mem_free(&qbuf);
413 prs_mem_free(&rbuf);
415 return result;
418 /* Query user groups */
420 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
421 POLICY_HND *user_pol, uint32 *num_groups,
422 DOM_GID **gid)
424 prs_struct qbuf, rbuf;
425 SAMR_Q_QUERY_USERGROUPS q;
426 SAMR_R_QUERY_USERGROUPS r;
427 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
429 DEBUG(10,("cli_samr_query_usergroups\n"));
431 ZERO_STRUCT(q);
432 ZERO_STRUCT(r);
434 /* Initialise parse structures */
436 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
437 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
439 /* Marshall data and send request */
441 init_samr_q_query_usergroups(&q, user_pol);
443 if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
444 !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
445 goto done;
447 /* Unmarshall response */
449 if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
450 goto done;
452 /* Return output parameters */
454 if (NT_STATUS_IS_OK(result = r.status)) {
455 *num_groups = r.num_entries;
456 *gid = r.gid;
459 done:
460 prs_mem_free(&qbuf);
461 prs_mem_free(&rbuf);
463 return result;
466 /* Query user aliases */
468 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
469 POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
470 uint32 *num_aliases, uint32 **als_rids)
472 prs_struct qbuf, rbuf;
473 SAMR_Q_QUERY_USERALIASES q;
474 SAMR_R_QUERY_USERALIASES r;
475 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
476 unsigned int ptr=1;
478 DEBUG(10,("cli_samr_query_useraliases\n"));
480 ZERO_STRUCT(q);
481 ZERO_STRUCT(r);
483 /* Initialise parse structures */
485 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
486 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
488 /* Marshall data and send request */
490 init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
492 if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
493 !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
494 goto done;
496 /* Unmarshall response */
498 if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
499 goto done;
501 /* Return output parameters */
503 if (NT_STATUS_IS_OK(result = r.status)) {
504 *num_aliases = r.num_entries;
505 *als_rids = r.rid;
508 done:
509 prs_mem_free(&qbuf);
510 prs_mem_free(&rbuf);
512 return result;
515 /* Query user groups */
517 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
518 POLICY_HND *group_pol, uint32 *num_mem,
519 uint32 **rid, uint32 **attr)
521 prs_struct qbuf, rbuf;
522 SAMR_Q_QUERY_GROUPMEM q;
523 SAMR_R_QUERY_GROUPMEM r;
524 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
526 DEBUG(10,("cli_samr_query_groupmem\n"));
528 ZERO_STRUCT(q);
529 ZERO_STRUCT(r);
531 /* Initialise parse structures */
533 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
534 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
536 /* Marshall data and send request */
538 init_samr_q_query_groupmem(&q, group_pol);
540 if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
541 !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
542 goto done;
544 /* Unmarshall response */
546 if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
547 goto done;
549 /* Return output parameters */
551 if (NT_STATUS_IS_OK(result = r.status)) {
552 *num_mem = r.num_entries;
553 *rid = r.rid;
554 *attr = r.attr;
557 done:
558 prs_mem_free(&qbuf);
559 prs_mem_free(&rbuf);
561 return result;
565 * Enumerate domain users
567 * @param cli client state structure
568 * @param mem_ctx talloc context
569 * @param pol opened domain policy handle
570 * @param start_idx starting index of enumeration, returns context for
571 next enumeration
572 * @param acb_mask account control bit mask (to enumerate some particular
573 * kind of accounts)
574 * @param size max acceptable size of response
575 * @param dom_users returned array of domain user names
576 * @param rids returned array of domain user RIDs
577 * @param num_dom_users numer returned entries
579 * @return NTSTATUS returned in rpc response
581 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
582 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
583 uint32 size, char ***dom_users, uint32 **rids,
584 uint32 *num_dom_users)
586 prs_struct qbuf;
587 prs_struct rbuf;
588 SAMR_Q_ENUM_DOM_USERS q;
589 SAMR_R_ENUM_DOM_USERS r;
590 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
591 int i;
593 DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
595 ZERO_STRUCT(q);
596 ZERO_STRUCT(r);
598 /* always init this */
599 *num_dom_users = 0;
601 /* Initialise parse structures */
603 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
604 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
606 /* Fill query structure with parameters */
608 init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
610 if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
611 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
612 goto done;
615 /* unpack received stream */
617 if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
618 goto done;
620 result = r.status;
622 if (!NT_STATUS_IS_OK(result) &&
623 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
624 goto done;
626 *start_idx = r.next_idx;
627 *num_dom_users = r.num_entries2;
629 if (r.num_entries2) {
630 /* allocate memory needed to return received data */
631 *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2);
632 if (!*rids) {
633 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
634 return NT_STATUS_NO_MEMORY;
637 *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2);
638 if (!*dom_users) {
639 DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
640 return NT_STATUS_NO_MEMORY;
643 /* fill output buffers with rpc response */
644 for (i = 0; i < r.num_entries2; i++) {
645 fstring conv_buf;
647 (*rids)[i] = r.sam[i].rid;
648 unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
649 (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
653 done:
654 prs_mem_free(&qbuf);
655 prs_mem_free(&rbuf);
657 return result;
660 /* Enumerate domain groups */
662 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
663 POLICY_HND *pol, uint32 *start_idx,
664 uint32 size, struct acct_info **dom_groups,
665 uint32 *num_dom_groups)
667 prs_struct qbuf, rbuf;
668 SAMR_Q_ENUM_DOM_GROUPS q;
669 SAMR_R_ENUM_DOM_GROUPS r;
670 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
671 uint32 name_idx, i;
673 DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
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_enum_dom_groups(&q, pol, *start_idx, size);
687 if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
688 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
689 goto done;
691 /* Unmarshall response */
693 if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
694 goto done;
696 /* Return output parameters */
698 result = r.status;
700 if (!NT_STATUS_IS_OK(result) &&
701 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
702 goto done;
704 *num_dom_groups = r.num_entries2;
706 if (*num_dom_groups == 0)
707 goto done;
709 if (!((*dom_groups) = (struct acct_info *)
710 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
711 result = NT_STATUS_NO_MEMORY;
712 goto done;
715 memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
717 name_idx = 0;
719 for (i = 0; i < *num_dom_groups; i++) {
721 (*dom_groups)[i].rid = r.sam[i].rid;
723 if (r.sam[i].hdr_name.buffer) {
724 unistr2_to_ascii((*dom_groups)[i].acct_name,
725 &r.uni_grp_name[name_idx],
726 sizeof(fstring) - 1);
727 name_idx++;
730 *start_idx = r.next_idx;
733 done:
734 prs_mem_free(&qbuf);
735 prs_mem_free(&rbuf);
737 return result;
740 /* Enumerate domain groups */
742 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
743 POLICY_HND *pol, uint32 *start_idx,
744 uint32 size, struct acct_info **dom_aliases,
745 uint32 *num_dom_aliases)
747 prs_struct qbuf, rbuf;
748 SAMR_Q_ENUM_DOM_ALIASES q;
749 SAMR_R_ENUM_DOM_ALIASES r;
750 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
751 uint32 name_idx, i;
753 DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
755 ZERO_STRUCT(q);
756 ZERO_STRUCT(r);
758 /* Initialise parse structures */
760 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
761 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
763 /* Marshall data and send request */
765 init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
767 if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
768 !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
769 goto done;
772 /* Unmarshall response */
774 if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
775 goto done;
778 /* Return output parameters */
780 result = r.status;
782 if (!NT_STATUS_IS_OK(result) &&
783 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
784 goto done;
787 *num_dom_aliases = r.num_entries2;
789 if (*num_dom_aliases == 0)
790 goto done;
792 if (!((*dom_aliases) = (struct acct_info *)
793 talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_aliases))) {
794 result = NT_STATUS_NO_MEMORY;
795 goto done;
798 memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
800 name_idx = 0;
802 for (i = 0; i < *num_dom_aliases; i++) {
804 (*dom_aliases)[i].rid = r.sam[i].rid;
806 if (r.sam[i].hdr_name.buffer) {
807 unistr2_to_ascii((*dom_aliases)[i].acct_name,
808 &r.uni_grp_name[name_idx],
809 sizeof(fstring) - 1);
810 name_idx++;
813 *start_idx = r.next_idx;
816 done:
817 prs_mem_free(&qbuf);
818 prs_mem_free(&rbuf);
820 return result;
823 /* Query alias members */
825 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
826 POLICY_HND *alias_pol, uint32 *num_mem,
827 DOM_SID **sids)
829 prs_struct qbuf, rbuf;
830 SAMR_Q_QUERY_ALIASMEM q;
831 SAMR_R_QUERY_ALIASMEM r;
832 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
833 uint32 i;
835 DEBUG(10,("cli_samr_query_aliasmem\n"));
837 ZERO_STRUCT(q);
838 ZERO_STRUCT(r);
840 /* Initialise parse structures */
842 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
843 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
845 /* Marshall data and send request */
847 init_samr_q_query_aliasmem(&q, alias_pol);
849 if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
850 !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
851 goto done;
854 /* Unmarshall response */
856 if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
857 goto done;
860 /* Return output parameters */
862 if (!NT_STATUS_IS_OK(result = r.status)) {
863 goto done;
866 *num_mem = r.num_sids;
868 if (*num_mem == 0) {
869 *sids = NULL;
870 result = NT_STATUS_OK;
871 goto done;
874 if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
875 result = NT_STATUS_UNSUCCESSFUL;
876 goto done;
879 for (i = 0; i < *num_mem; i++) {
880 (*sids)[i] = r.sid[i].sid;
883 done:
884 prs_mem_free(&qbuf);
885 prs_mem_free(&rbuf);
887 return result;
890 /* Open handle on an alias */
892 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
893 POLICY_HND *domain_pol, uint32 access_mask,
894 uint32 alias_rid, POLICY_HND *alias_pol)
896 prs_struct qbuf, rbuf;
897 SAMR_Q_OPEN_ALIAS q;
898 SAMR_R_OPEN_ALIAS r;
899 NTSTATUS result;
901 DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
903 ZERO_STRUCT(q);
904 ZERO_STRUCT(r);
906 /* Initialise parse structures */
908 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
909 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
911 /* Marshall data and send request */
913 init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
915 if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
916 !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
917 result = NT_STATUS_UNSUCCESSFUL;
918 goto done;
921 /* Unmarshall response */
923 if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
924 result = NT_STATUS_UNSUCCESSFUL;
925 goto done;
928 /* Return output parameters */
930 if (NT_STATUS_IS_OK(result = r.status)) {
931 *alias_pol = r.pol;
932 #ifdef __INSURE__
933 alias_pol->marker = malloc(1);
934 #endif
937 done:
938 prs_mem_free(&qbuf);
939 prs_mem_free(&rbuf);
941 return result;
944 /* Query alias info */
946 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
947 POLICY_HND *alias_pol, uint16 switch_value,
948 ALIAS_INFO_CTR *ctr)
950 prs_struct qbuf, rbuf;
951 SAMR_Q_QUERY_ALIASINFO q;
952 SAMR_R_QUERY_ALIASINFO r;
953 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
955 DEBUG(10,("cli_samr_query_dom_info\n"));
957 ZERO_STRUCT(q);
958 ZERO_STRUCT(r);
960 /* Initialise parse structures */
962 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
963 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
965 /* Marshall data and send request */
967 init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
969 if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
970 !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
971 goto done;
974 /* Unmarshall response */
976 if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
977 goto done;
980 /* Return output parameters */
982 if (!NT_STATUS_IS_OK(result = r.status)) {
983 goto done;
986 *ctr = r.ctr;
988 done:
989 prs_mem_free(&qbuf);
990 prs_mem_free(&rbuf);
992 return result;
995 /* Query domain info */
997 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
998 POLICY_HND *domain_pol, uint16 switch_value,
999 SAM_UNK_CTR *ctr)
1001 prs_struct qbuf, rbuf;
1002 SAMR_Q_QUERY_DOMAIN_INFO q;
1003 SAMR_R_QUERY_DOMAIN_INFO r;
1004 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1006 DEBUG(10,("cli_samr_query_dom_info\n"));
1008 ZERO_STRUCT(q);
1009 ZERO_STRUCT(r);
1011 /* Initialise parse structures */
1013 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1014 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1016 /* Marshall data and send request */
1018 init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1020 if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1021 !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1022 goto done;
1025 /* Unmarshall response */
1027 r.ctr = ctr;
1029 if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1030 goto done;
1033 /* Return output parameters */
1035 if (!NT_STATUS_IS_OK(result = r.status)) {
1036 goto done;
1039 done:
1040 prs_mem_free(&qbuf);
1041 prs_mem_free(&rbuf);
1043 return result;
1046 /* User change password */
1048 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1049 const char *username,
1050 const char *newpassword,
1051 const char *oldpassword )
1053 prs_struct qbuf, rbuf;
1054 SAMR_Q_CHGPASSWD_USER q;
1055 SAMR_R_CHGPASSWD_USER r;
1056 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1058 uchar new_nt_password[516];
1059 uchar new_lm_password[516];
1060 uchar old_nt_hash[16];
1061 uchar old_lanman_hash[16];
1062 uchar old_nt_hash_enc[16];
1063 uchar old_lanman_hash_enc[16];
1065 uchar new_nt_hash[16];
1066 uchar new_lanman_hash[16];
1068 DEBUG(10,("cli_samr_query_dom_info\n"));
1070 ZERO_STRUCT(q);
1071 ZERO_STRUCT(r);
1073 /* Calculate the MD4 hash (NT compatible) of the password */
1074 E_md4hash(oldpassword, old_nt_hash);
1075 E_md4hash(newpassword, new_nt_hash);
1077 if (lp_client_lanman_auth()
1078 && E_deshash(newpassword, new_lanman_hash)
1079 && E_deshash(oldpassword, old_lanman_hash)) {
1080 /* E_deshash returns false for 'long' passwords (> 14
1081 DOS chars). This allows us to match Win2k, which
1082 does not store a LM hash for these passwords (which
1083 would reduce the effective password length to 14) */
1085 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1087 SamOEMhash( new_lm_password, old_nt_hash, 516);
1088 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1089 } else {
1090 ZERO_STRUCT(new_lm_password);
1091 ZERO_STRUCT(old_lanman_hash_enc);
1094 encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1096 SamOEMhash( new_nt_password, old_nt_hash, 516);
1097 E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1099 /* Initialise parse structures */
1101 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1102 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1104 /* Marshall data and send request */
1106 init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username,
1107 new_nt_password,
1108 old_nt_hash_enc,
1109 new_lm_password,
1110 old_lanman_hash_enc);
1112 if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1113 !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1114 goto done;
1117 /* Unmarshall response */
1119 if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1120 goto done;
1123 /* Return output parameters */
1125 if (!NT_STATUS_IS_OK(result = r.status)) {
1126 goto done;
1129 done:
1130 prs_mem_free(&qbuf);
1131 prs_mem_free(&rbuf);
1133 return result;
1136 /* This function returns the bizzare set of (max_entries, max_size) required
1137 for the QueryDisplayInfo RPC to actually work against a domain controller
1138 with large (10k and higher) numbers of users. These values were
1139 obtained by inspection using ethereal and NT4 running User Manager. */
1141 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1142 uint32 *max_size)
1144 switch(loop_count) {
1145 case 0:
1146 *max_entries = 512;
1147 *max_size = 16383;
1148 break;
1149 case 1:
1150 *max_entries = 1024;
1151 *max_size = 32766;
1152 break;
1153 case 2:
1154 *max_entries = 2048;
1155 *max_size = 65532;
1156 break;
1157 case 3:
1158 *max_entries = 4096;
1159 *max_size = 131064;
1160 break;
1161 default: /* loop_count >= 4 */
1162 *max_entries = 4096;
1163 *max_size = 131071;
1164 break;
1168 /* Query display info */
1170 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1171 POLICY_HND *domain_pol, uint32 *start_idx,
1172 uint16 switch_value, uint32 *num_entries,
1173 uint32 max_entries, uint32 max_size,
1174 SAM_DISPINFO_CTR *ctr)
1176 prs_struct qbuf, rbuf;
1177 SAMR_Q_QUERY_DISPINFO q;
1178 SAMR_R_QUERY_DISPINFO r;
1179 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1181 DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1183 ZERO_STRUCT(q);
1184 ZERO_STRUCT(r);
1186 *num_entries = 0;
1188 /* Initialise parse structures */
1190 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1191 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1193 /* Marshall data and send request */
1195 init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1196 *start_idx, max_entries, max_size);
1198 if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1199 !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1200 goto done;
1203 /* Unmarshall response */
1205 r.ctr = ctr;
1207 if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1208 goto done;
1211 /* Return output parameters */
1213 result = r.status;
1215 if (!NT_STATUS_IS_OK(result) &&
1216 NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1217 goto done;
1220 *num_entries = r.num_entries;
1221 *start_idx += r.num_entries; /* No next_idx in this structure! */
1223 done:
1224 prs_mem_free(&qbuf);
1225 prs_mem_free(&rbuf);
1227 return result;
1230 /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
1231 looked up in one packet. */
1233 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1234 POLICY_HND *domain_pol, uint32 flags,
1235 uint32 num_rids, uint32 *rids,
1236 uint32 *num_names, char ***names,
1237 uint32 **name_types)
1239 prs_struct qbuf, rbuf;
1240 SAMR_Q_LOOKUP_RIDS q;
1241 SAMR_R_LOOKUP_RIDS r;
1242 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1243 uint32 i;
1245 DEBUG(10,("cli_samr_lookup_rids\n"));
1247 if (num_rids > 1000) {
1248 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1249 "more than ~1000 rids are looked up at once.\n"));
1252 ZERO_STRUCT(q);
1253 ZERO_STRUCT(r);
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 */
1262 init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1263 num_rids, rids);
1265 if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1266 !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1267 goto done;
1270 /* Unmarshall response */
1272 if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1273 goto done;
1276 /* Return output parameters */
1278 if (!NT_STATUS_IS_OK(result = r.status)) {
1279 goto done;
1282 if (r.num_names1 == 0) {
1283 *num_names = 0;
1284 *names = NULL;
1285 goto done;
1288 *num_names = r.num_names1;
1289 *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
1290 *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
1292 for (i = 0; i < r.num_names1; i++) {
1293 fstring tmp;
1295 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1296 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1297 (*name_types)[i] = r.type[i];
1300 done:
1301 prs_mem_free(&qbuf);
1302 prs_mem_free(&rbuf);
1304 return result;
1307 /* Lookup names */
1309 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1310 POLICY_HND *domain_pol, uint32 flags,
1311 uint32 num_names, const char **names,
1312 uint32 *num_rids, uint32 **rids,
1313 uint32 **rid_types)
1315 prs_struct qbuf, rbuf;
1316 SAMR_Q_LOOKUP_NAMES q;
1317 SAMR_R_LOOKUP_NAMES r;
1318 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1319 uint32 i;
1321 DEBUG(10,("cli_samr_lookup_names\n"));
1323 ZERO_STRUCT(q);
1324 ZERO_STRUCT(r);
1326 /* Initialise parse structures */
1328 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1329 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1331 /* Marshall data and send request */
1333 init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1334 num_names, names);
1336 if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1337 !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1338 goto done;
1341 /* Unmarshall response */
1343 if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1344 goto done;
1347 /* Return output parameters */
1349 if (!NT_STATUS_IS_OK(result = r.status)) {
1350 goto done;
1353 if (r.num_rids1 == 0) {
1354 *num_rids = 0;
1355 goto done;
1358 *num_rids = r.num_rids1;
1359 *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1360 *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1362 for (i = 0; i < r.num_rids1; i++) {
1363 (*rids)[i] = r.rids[i];
1364 (*rid_types)[i] = r.types[i];
1367 done:
1368 prs_mem_free(&qbuf);
1369 prs_mem_free(&rbuf);
1371 return result;
1374 /* Create a domain user */
1376 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1377 POLICY_HND *domain_pol, const char *acct_name,
1378 uint32 acb_info, uint32 unknown,
1379 POLICY_HND *user_pol, uint32 *rid)
1381 prs_struct qbuf, rbuf;
1382 SAMR_Q_CREATE_USER q;
1383 SAMR_R_CREATE_USER r;
1384 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1386 DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1388 ZERO_STRUCT(q);
1389 ZERO_STRUCT(r);
1391 /* Initialise parse structures */
1393 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1394 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1396 /* Marshall data and send request */
1398 init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1400 if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1401 !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1402 goto done;
1405 /* Unmarshall response */
1407 if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1408 goto done;
1411 /* Return output parameters */
1413 if (!NT_STATUS_IS_OK(result = r.status)) {
1414 goto done;
1417 if (user_pol)
1418 *user_pol = r.user_pol;
1420 if (rid)
1421 *rid = r.user_rid;
1423 done:
1424 prs_mem_free(&qbuf);
1425 prs_mem_free(&rbuf);
1427 return result;
1430 /* Set userinfo */
1432 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1433 POLICY_HND *user_pol, uint16 switch_value,
1434 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1436 prs_struct qbuf, rbuf;
1437 SAMR_Q_SET_USERINFO q;
1438 SAMR_R_SET_USERINFO r;
1439 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1441 DEBUG(10,("cli_samr_set_userinfo\n"));
1443 ZERO_STRUCT(q);
1444 ZERO_STRUCT(r);
1446 if (!sess_key->length) {
1447 DEBUG(1, ("No user session key\n"));
1448 return NT_STATUS_NO_USER_SESSION_KEY;
1451 /* Initialise parse structures */
1453 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1454 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1456 /* Marshall data and send request */
1458 q.ctr = ctr;
1460 init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1461 ctr->info.id);
1463 if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1464 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1465 goto done;
1468 /* Unmarshall response */
1470 if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1471 goto done;
1474 /* Return output parameters */
1476 if (!NT_STATUS_IS_OK(result = r.status)) {
1477 goto done;
1480 done:
1481 prs_mem_free(&qbuf);
1482 prs_mem_free(&rbuf);
1484 return result;
1487 /* Set userinfo2 */
1489 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1490 POLICY_HND *user_pol, uint16 switch_value,
1491 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1493 prs_struct qbuf, rbuf;
1494 SAMR_Q_SET_USERINFO2 q;
1495 SAMR_R_SET_USERINFO2 r;
1496 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1498 DEBUG(10,("cli_samr_set_userinfo2\n"));
1500 if (!sess_key->length) {
1501 DEBUG(1, ("No user session key\n"));
1502 return NT_STATUS_NO_USER_SESSION_KEY;
1505 ZERO_STRUCT(q);
1506 ZERO_STRUCT(r);
1508 /* Initialise parse structures */
1510 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1511 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1513 /* Marshall data and send request */
1515 init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1517 if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1518 !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1519 goto done;
1522 /* Unmarshall response */
1524 if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1525 goto done;
1528 /* Return output parameters */
1530 if (!NT_STATUS_IS_OK(result = r.status)) {
1531 goto done;
1534 done:
1535 prs_mem_free(&qbuf);
1536 prs_mem_free(&rbuf);
1538 return result;
1541 /* Delete domain user */
1543 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1544 POLICY_HND *user_pol)
1546 prs_struct qbuf, rbuf;
1547 SAMR_Q_DELETE_DOM_USER q;
1548 SAMR_R_DELETE_DOM_USER r;
1549 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1551 DEBUG(10,("cli_samr_delete_dom_user\n"));
1553 ZERO_STRUCT(q);
1554 ZERO_STRUCT(r);
1556 /* Initialise parse structures */
1558 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1559 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1561 /* Marshall data and send request */
1563 init_samr_q_delete_dom_user(&q, user_pol);
1565 if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1566 !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1567 goto done;
1570 /* Unmarshall response */
1572 if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1573 goto done;
1576 /* Return output parameters */
1578 result = r.status;
1580 done:
1581 prs_mem_free(&qbuf);
1582 prs_mem_free(&rbuf);
1584 return result;
1587 /* Query user security object */
1589 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1590 POLICY_HND *user_pol, uint16 switch_value,
1591 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1593 prs_struct qbuf, rbuf;
1594 SAMR_Q_QUERY_SEC_OBJ q;
1595 SAMR_R_QUERY_SEC_OBJ r;
1596 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1598 DEBUG(10,("cli_samr_query_sec_obj\n"));
1600 ZERO_STRUCT(q);
1601 ZERO_STRUCT(r);
1603 /* Initialise parse structures */
1605 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1606 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1608 /* Marshall data and send request */
1610 init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1612 if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1613 !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1614 goto done;
1617 /* Unmarshall response */
1619 if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1620 goto done;
1623 /* Return output parameters */
1625 result = r.status;
1626 *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1628 done:
1629 prs_mem_free(&qbuf);
1630 prs_mem_free(&rbuf);
1632 return result;
1635 /* Get domain password info */
1637 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1638 uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
1640 prs_struct qbuf, rbuf;
1641 SAMR_Q_GET_DOM_PWINFO q;
1642 SAMR_R_GET_DOM_PWINFO r;
1643 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1645 DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
1647 ZERO_STRUCT(q);
1648 ZERO_STRUCT(r);
1650 /* Initialise parse structures */
1652 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1653 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1655 /* Marshall data and send request */
1657 init_samr_q_get_dom_pwinfo(&q, cli->desthost);
1659 if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
1660 !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
1661 goto done;
1663 /* Unmarshall response */
1665 if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
1666 goto done;
1668 /* Return output parameters */
1670 result = r.status;
1672 if (NT_STATUS_IS_OK(result)) {
1673 if (unk_0)
1674 *unk_0 = r.unk_0;
1675 if (unk_1)
1676 *unk_1 = r.unk_1;
1677 if (unk_2)
1678 *unk_2 = r.unk_2;
1681 done:
1682 prs_mem_free(&qbuf);
1683 prs_mem_free(&rbuf);
1685 return result;
1688 /* Lookup Domain Name */
1690 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1691 POLICY_HND *user_pol, char *domain_name,
1692 DOM_SID *sid)
1694 prs_struct qbuf, rbuf;
1695 SAMR_Q_LOOKUP_DOMAIN q;
1696 SAMR_R_LOOKUP_DOMAIN r;
1697 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1699 DEBUG(10,("cli_samr_lookup_domain\n"));
1701 ZERO_STRUCT(q);
1702 ZERO_STRUCT(r);
1704 /* Initialise parse structures */
1706 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1707 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1709 /* Marshall data and send request */
1711 init_samr_q_lookup_domain(&q, user_pol, domain_name);
1713 if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
1714 !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
1715 goto done;
1717 /* Unmarshall response */
1719 if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
1720 goto done;
1722 /* Return output parameters */
1724 result = r.status;
1726 if (NT_STATUS_IS_OK(result))
1727 sid_copy(sid, &r.dom_sid.sid);
1729 done:
1730 prs_mem_free(&qbuf);
1731 prs_mem_free(&rbuf);
1733 return result;