netapi: implement NetUserModalsSet_r.
[Samba.git] / source / lib / netapi / user.c
blobff807997ae3f39bbc0029a8c5059a66a1f72b852
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi User Support
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
27 /****************************************************************
28 ****************************************************************/
30 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
31 struct samr_UserInfo21 *info21)
33 uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS;
34 struct samr_LogonHours zero_logon_hours;
35 struct lsa_BinaryString zero_parameters;
36 uint32_t acct_flags = 0;
37 NTTIME password_age;
39 ZERO_STRUCTP(info21);
40 ZERO_STRUCT(zero_logon_hours);
41 ZERO_STRUCT(zero_parameters);
43 if (infoX->usriX_name) {
44 fields_present |= SAMR_FIELD_FULL_NAME;
46 if (infoX->usriX_password) {
47 fields_present |= SAMR_FIELD_PASSWORD;
49 if (infoX->usriX_flags) {
50 fields_present |= SAMR_FIELD_ACCT_FLAGS;
52 if (infoX->usriX_name) {
53 fields_present |= SAMR_FIELD_FULL_NAME;
55 if (infoX->usriX_home_dir) {
56 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
58 if (infoX->usriX_script_path) {
59 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
61 if (infoX->usriX_comment) {
62 fields_present |= SAMR_FIELD_DESCRIPTION;
64 if (infoX->usriX_password_age) {
65 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
68 acct_flags |= infoX->usriX_flags | ACB_NORMAL;
70 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
72 /* TODO: infoX->usriX_priv */
73 init_samr_user_info21(info21,
79 password_age,
80 NULL,
81 infoX->usriX_name,
82 infoX->usriX_home_dir,
83 NULL,
84 infoX->usriX_script_path,
85 NULL,
86 infoX->usriX_comment,
87 NULL,
88 NULL,
89 &zero_parameters,
92 acct_flags,
93 fields_present,
94 zero_logon_hours,
104 /****************************************************************
105 ****************************************************************/
107 static NTSTATUS construct_USER_INFO_X(uint32_t level,
108 uint8_t *buffer,
109 struct USER_INFO_X *uX)
111 struct USER_INFO_0 *u0 = NULL;
112 struct USER_INFO_1 *u1 = NULL;
113 struct USER_INFO_2 *u2 = NULL;
114 struct USER_INFO_1007 *u1007 = NULL;
116 if (!buffer || !uX) {
117 return NT_STATUS_INVALID_PARAMETER;
120 ZERO_STRUCTP(uX);
122 switch (level) {
123 case 0:
124 u0 = (struct USER_INFO_0 *)buffer;
125 uX->usriX_name = u0->usri0_name;
126 break;
127 case 1:
128 u1 = (struct USER_INFO_1 *)buffer;
129 uX->usriX_name = u1->usri1_name;
130 uX->usriX_password = u1->usri1_password;
131 uX->usriX_password_age = u1->usri1_password_age;
132 uX->usriX_priv = u1->usri1_priv;
133 uX->usriX_home_dir = u1->usri1_home_dir;
134 uX->usriX_comment = u1->usri1_comment;
135 uX->usriX_flags = u1->usri1_flags;
136 uX->usriX_script_path = u1->usri1_script_path;
137 break;
138 case 2:
139 u2 = (struct USER_INFO_2 *)buffer;
140 uX->usriX_name = u2->usri2_name;
141 uX->usriX_password = u2->usri2_password;
142 uX->usriX_password_age = u2->usri2_password_age;
143 uX->usriX_priv = u2->usri2_priv;
144 uX->usriX_home_dir = u2->usri2_home_dir;
145 uX->usriX_comment = u2->usri2_comment;
146 uX->usriX_flags = u2->usri2_flags;
147 uX->usriX_script_path = u2->usri2_script_path;
148 uX->usriX_auth_flags = u2->usri2_auth_flags;
149 uX->usriX_full_name = u2->usri2_full_name;
150 uX->usriX_usr_comment = u2->usri2_usr_comment;
151 uX->usriX_parms = u2->usri2_parms;
152 uX->usriX_workstations = u2->usri2_workstations;
153 uX->usriX_last_logon = u2->usri2_last_logon;
154 uX->usriX_last_logoff = u2->usri2_last_logoff;
155 uX->usriX_acct_expires = u2->usri2_acct_expires;
156 uX->usriX_max_storage = u2->usri2_max_storage;
157 uX->usriX_units_per_week= u2->usri2_units_per_week;
158 uX->usriX_logon_hours = u2->usri2_logon_hours;
159 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
160 uX->usriX_num_logons = u2->usri2_num_logons;
161 uX->usriX_logon_server = u2->usri2_logon_server;
162 uX->usriX_country_code = u2->usri2_country_code;
163 uX->usriX_code_page = u2->usri2_code_page;
164 break;
165 case 1007:
166 u1007 = (struct USER_INFO_1007 *)buffer;
167 uX->usriX_comment = u1007->usri1007_comment;
168 break;
169 case 3:
170 case 4:
171 default:
172 return NT_STATUS_INVALID_INFO_CLASS;
175 return NT_STATUS_OK;
178 /****************************************************************
179 ****************************************************************/
181 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
182 struct NetUserAdd *r)
184 struct cli_state *cli = NULL;
185 struct rpc_pipe_client *pipe_cli = NULL;
186 NTSTATUS status;
187 WERROR werr;
188 POLICY_HND connect_handle, domain_handle, user_handle;
189 struct lsa_String lsa_account_name;
190 struct dom_sid2 *domain_sid = NULL;
191 struct samr_UserInfo21 info21;
192 union samr_UserInfo *user_info = NULL;
193 struct samr_PwInfo pw_info;
194 uint32_t access_granted = 0;
195 uint32_t rid = 0;
196 struct USER_INFO_X uX;
198 ZERO_STRUCT(connect_handle);
199 ZERO_STRUCT(domain_handle);
200 ZERO_STRUCT(user_handle);
202 if (!r->in.buffer) {
203 return WERR_INVALID_PARAM;
206 switch (r->in.level) {
207 case 1:
208 break;
209 case 2:
210 case 3:
211 case 4:
212 default:
213 werr = WERR_NOT_SUPPORTED;
214 goto done;
217 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
218 if (!W_ERROR_IS_OK(werr)) {
219 goto done;
222 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
223 &pipe_cli);
224 if (!W_ERROR_IS_OK(werr)) {
225 goto done;
228 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
229 if (!NT_STATUS_IS_OK(status)) {
230 werr = ntstatus_to_werror(status);
231 goto done;
234 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
235 SAMR_ACCESS_ENUM_DOMAINS |
236 SAMR_ACCESS_OPEN_DOMAIN,
237 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
238 SAMR_DOMAIN_ACCESS_CREATE_USER |
239 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
240 &connect_handle,
241 &domain_handle,
242 &domain_sid);
243 if (!W_ERROR_IS_OK(werr)) {
244 goto done;
247 init_lsa_String(&lsa_account_name, uX.usriX_name);
249 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
250 &domain_handle,
251 &lsa_account_name,
252 ACB_NORMAL,
253 SEC_STD_WRITE_DAC |
254 SEC_STD_DELETE |
255 SAMR_USER_ACCESS_SET_PASSWORD |
256 SAMR_USER_ACCESS_SET_ATTRIBUTES |
257 SAMR_USER_ACCESS_GET_ATTRIBUTES,
258 &user_handle,
259 &access_granted,
260 &rid);
261 if (!NT_STATUS_IS_OK(status)) {
262 werr = ntstatus_to_werror(status);
263 goto done;
266 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
267 &user_handle,
269 &user_info);
270 if (!NT_STATUS_IS_OK(status)) {
271 werr = ntstatus_to_werror(status);
272 goto done;
275 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
276 werr = WERR_INVALID_PARAM;
277 goto done;
280 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
281 &user_handle,
282 &pw_info);
283 if (!NT_STATUS_IS_OK(status)) {
284 werr = ntstatus_to_werror(status);
285 goto done;
288 convert_USER_INFO_X_to_samr_user_info21(&uX,
289 &info21);
291 ZERO_STRUCTP(user_info);
293 if (uX.usriX_password) {
295 user_info->info25.info = info21;
297 init_samr_CryptPasswordEx(uX.usriX_password,
298 &cli->user_session_key,
299 &user_info->info25.password);
301 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
302 &user_handle,
304 user_info);
306 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
308 user_info->info23.info = info21;
310 init_samr_CryptPassword(uX.usriX_password,
311 &cli->user_session_key,
312 &user_info->info23.password);
314 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
315 &user_handle,
317 user_info);
319 } else {
321 user_info->info21 = info21;
323 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
324 &user_handle,
326 user_info);
329 if (!NT_STATUS_IS_OK(status)) {
330 werr = ntstatus_to_werror(status);
331 goto failed;
334 werr = WERR_OK;
335 goto done;
337 failed:
338 rpccli_samr_DeleteUser(pipe_cli, ctx,
339 &user_handle);
341 done:
342 if (!cli) {
343 return werr;
346 if (is_valid_policy_hnd(&user_handle)) {
347 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
350 if (ctx->disable_policy_handle_cache) {
351 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
352 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
355 return werr;
358 /****************************************************************
359 ****************************************************************/
361 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
362 struct NetUserAdd *r)
364 /* for now just talk to local RPC server */
365 if (!r->in.server_name) {
366 r->in.server_name = "localhost";
369 return NetUserAdd_r(ctx, r);
372 /****************************************************************
373 ****************************************************************/
375 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
376 struct NetUserDel *r)
378 struct cli_state *cli = NULL;
379 struct rpc_pipe_client *pipe_cli = NULL;
380 NTSTATUS status;
381 WERROR werr;
382 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
383 struct lsa_String lsa_account_name;
384 struct samr_Ids user_rids, name_types;
385 struct dom_sid2 *domain_sid = NULL;
386 struct dom_sid2 user_sid;
388 ZERO_STRUCT(connect_handle);
389 ZERO_STRUCT(builtin_handle);
390 ZERO_STRUCT(domain_handle);
391 ZERO_STRUCT(user_handle);
393 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
394 if (!W_ERROR_IS_OK(werr)) {
395 goto done;
398 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
399 &pipe_cli);
400 if (!W_ERROR_IS_OK(werr)) {
401 goto done;
404 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
405 SAMR_ACCESS_ENUM_DOMAINS |
406 SAMR_ACCESS_OPEN_DOMAIN,
407 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
408 &connect_handle,
409 &domain_handle,
410 &domain_sid);
411 if (!W_ERROR_IS_OK(werr)) {
412 goto done;
415 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
416 &connect_handle,
417 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
418 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
419 &builtin_handle);
420 if (!NT_STATUS_IS_OK(status)) {
421 werr = ntstatus_to_werror(status);
422 goto done;
425 init_lsa_String(&lsa_account_name, r->in.user_name);
427 status = rpccli_samr_LookupNames(pipe_cli, ctx,
428 &domain_handle,
430 &lsa_account_name,
431 &user_rids,
432 &name_types);
433 if (!NT_STATUS_IS_OK(status)) {
434 werr = ntstatus_to_werror(status);
435 goto done;
438 status = rpccli_samr_OpenUser(pipe_cli, ctx,
439 &domain_handle,
440 STD_RIGHT_DELETE_ACCESS,
441 user_rids.ids[0],
442 &user_handle);
443 if (!NT_STATUS_IS_OK(status)) {
444 werr = ntstatus_to_werror(status);
445 goto done;
448 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
450 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
451 &builtin_handle,
452 &user_sid);
453 if (!NT_STATUS_IS_OK(status)) {
454 werr = ntstatus_to_werror(status);
455 goto done;
458 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
459 &user_handle);
460 if (!NT_STATUS_IS_OK(status)) {
461 werr = ntstatus_to_werror(status);
462 goto done;
465 werr = WERR_OK;
467 done:
468 if (!cli) {
469 return werr;
472 if (is_valid_policy_hnd(&user_handle)) {
473 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
476 if (ctx->disable_policy_handle_cache) {
477 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
478 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
479 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
482 return werr;
485 /****************************************************************
486 ****************************************************************/
488 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
489 struct NetUserDel *r)
491 /* for now just talk to local RPC server */
492 if (!r->in.server_name) {
493 r->in.server_name = "localhost";
496 return NetUserDel_r(ctx, r);
499 /****************************************************************
500 ****************************************************************/
502 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
503 struct rpc_pipe_client *pipe_cli,
504 struct policy_handle *domain_handle,
505 struct policy_handle *builtin_handle,
506 const char *user_name,
507 uint32_t rid,
508 uint32_t level,
509 struct samr_UserInfo21 **info21,
510 struct sec_desc_buf **sec_desc)
512 NTSTATUS status;
514 struct policy_handle user_handle;
515 union samr_UserInfo *user_info = NULL;
516 struct samr_RidWithAttributeArray *rid_array = NULL;
517 uint32_t access_mask = SEC_STD_READ_CONTROL |
518 SAMR_USER_ACCESS_GET_ATTRIBUTES |
519 SAMR_USER_ACCESS_GET_NAME_ETC;
521 ZERO_STRUCT(user_handle);
523 switch (level) {
524 case 0:
525 case 1:
526 case 2:
527 case 3:
528 case 10:
529 case 11:
530 case 20:
531 case 23:
532 break;
533 default:
534 return NT_STATUS_INVALID_LEVEL;
537 if (level == 0) {
538 return NT_STATUS_OK;
541 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
542 domain_handle,
543 access_mask,
544 rid,
545 &user_handle);
546 if (!NT_STATUS_IS_OK(status)) {
547 goto done;
550 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
551 &user_handle,
553 &user_info);
554 if (!NT_STATUS_IS_OK(status)) {
555 goto done;
558 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
559 &user_handle,
560 SECINFO_DACL,
561 sec_desc);
562 if (!NT_STATUS_IS_OK(status)) {
563 goto done;
566 if (level == 1) {
567 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
568 &user_handle,
569 &rid_array);
570 if (!NT_STATUS_IS_OK(status)) {
571 goto done;
574 #if 0
575 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
576 &builtin_handle,
577 &sids,
578 &rids);
579 if (!NT_STATUS_IS_OK(status)) {
580 goto done;
582 #endif
585 *info21 = &user_info->info21;
587 done:
588 if (is_valid_policy_hnd(&user_handle)) {
589 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
592 return status;
595 /****************************************************************
596 ****************************************************************/
598 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
599 struct rpc_pipe_client *pipe_cli,
600 struct dom_sid *domain_sid,
601 struct policy_handle *domain_handle,
602 struct policy_handle *builtin_handle,
603 const char *user_name,
604 uint32_t rid,
605 uint32_t level,
606 uint8_t **buffer,
607 uint32_t *num_entries)
609 NTSTATUS status;
611 struct samr_UserInfo21 *info21 = NULL;
612 struct sec_desc_buf *sec_desc = NULL;
613 struct dom_sid sid;
615 struct USER_INFO_0 info0;
616 struct USER_INFO_10 info10;
617 struct USER_INFO_20 info20;
618 struct USER_INFO_23 info23;
620 switch (level) {
621 case 0:
622 case 1:
623 case 2:
624 case 3:
625 case 10:
626 case 11:
627 case 20:
628 case 23:
629 break;
630 default:
631 return NT_STATUS_INVALID_LEVEL;
634 if (level == 0) {
635 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
636 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
638 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
639 (struct USER_INFO_0 **)buffer, num_entries);
641 return NT_STATUS_OK;
644 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
645 domain_handle,
646 builtin_handle,
647 user_name,
648 rid,
649 level,
650 &info21,
651 &sec_desc);
653 if (!NT_STATUS_IS_OK(status)) {
654 goto done;
657 switch (level) {
658 case 10:
659 info10.usri10_name = talloc_strdup(mem_ctx, user_name);
660 NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
662 info10.usri10_comment = talloc_strdup(mem_ctx,
663 info21->description.string);
665 info10.usri10_full_name = talloc_strdup(mem_ctx,
666 info21->full_name.string);
668 info10.usri10_usr_comment = talloc_strdup(mem_ctx,
669 info21->comment.string);
671 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
672 (struct USER_INFO_10 **)buffer, num_entries);
674 break;
676 case 20:
677 info20.usri20_name = talloc_strdup(mem_ctx, user_name);
678 NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
680 info20.usri20_comment = talloc_strdup(mem_ctx,
681 info21->description.string);
683 info20.usri20_full_name = talloc_strdup(mem_ctx,
684 info21->full_name.string);
686 info20.usri20_flags = info21->acct_flags;
687 info20.usri20_user_id = rid;
689 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
690 (struct USER_INFO_20 **)buffer, num_entries);
692 break;
693 case 23:
694 info23.usri23_name = talloc_strdup(mem_ctx, user_name);
695 NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
697 info23.usri23_comment = talloc_strdup(mem_ctx,
698 info21->description.string);
700 info23.usri23_full_name = talloc_strdup(mem_ctx,
701 info21->full_name.string);
703 info23.usri23_flags = info21->acct_flags;
705 if (!sid_compose(&sid, domain_sid, rid)) {
706 return NT_STATUS_NO_MEMORY;
709 info23.usri23_user_sid =
710 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
712 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
713 (struct USER_INFO_23 **)buffer, num_entries);
714 break;
717 done:
718 return status;
721 /****************************************************************
722 ****************************************************************/
724 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
725 struct NetUserEnum *r)
727 struct cli_state *cli = NULL;
728 struct rpc_pipe_client *pipe_cli = NULL;
729 struct policy_handle connect_handle;
730 struct dom_sid2 *domain_sid = NULL;
731 struct policy_handle domain_handle;
732 struct samr_SamArray *sam = NULL;
733 uint32_t filter = ACB_NORMAL;
734 int i;
735 uint32_t entries_read = 0;
737 NTSTATUS status = NT_STATUS_OK;
738 WERROR werr;
740 ZERO_STRUCT(connect_handle);
741 ZERO_STRUCT(domain_handle);
743 if (!r->out.buffer) {
744 return WERR_INVALID_PARAM;
747 *r->out.buffer = NULL;
748 *r->out.entries_read = 0;
750 switch (r->in.level) {
751 case 0:
752 case 10:
753 case 20:
754 case 23:
755 break;
756 case 1:
757 case 2:
758 case 3:
759 case 11:
760 default:
761 return WERR_NOT_SUPPORTED;
764 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
765 if (!W_ERROR_IS_OK(werr)) {
766 goto done;
769 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
770 &pipe_cli);
771 if (!W_ERROR_IS_OK(werr)) {
772 goto done;
775 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
776 SAMR_ACCESS_ENUM_DOMAINS |
777 SAMR_ACCESS_OPEN_DOMAIN,
778 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
779 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
780 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
781 &connect_handle,
782 &domain_handle,
783 &domain_sid);
784 if (!W_ERROR_IS_OK(werr)) {
785 goto done;
788 switch (r->in.filter) {
789 case FILTER_NORMAL_ACCOUNT:
790 filter = ACB_NORMAL;
791 break;
792 case FILTER_TEMP_DUPLICATE_ACCOUNT:
793 filter = ACB_TEMPDUP;
794 break;
795 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
796 filter = ACB_DOMTRUST;
797 break;
798 case FILTER_WORKSTATION_TRUST_ACCOUNT:
799 filter = ACB_WSTRUST;
800 break;
801 case FILTER_SERVER_TRUST_ACCOUNT:
802 filter = ACB_SVRTRUST;
803 break;
804 default:
805 break;
808 status = rpccli_samr_EnumDomainUsers(pipe_cli,
809 ctx,
810 &domain_handle,
811 r->in.resume_handle,
812 filter,
813 &sam,
814 r->in.prefmaxlen,
815 &entries_read);
816 werr = ntstatus_to_werror(status);
817 if (NT_STATUS_IS_ERR(status)) {
818 goto done;
821 for (i=0; i < sam->count; i++) {
823 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
824 domain_sid,
825 &domain_handle,
826 NULL, /*&builtin_handle, */
827 sam->entries[i].name.string,
828 sam->entries[i].idx,
829 r->in.level,
830 r->out.buffer,
831 r->out.entries_read);
832 if (!NT_STATUS_IS_OK(status)) {
833 werr = ntstatus_to_werror(status);
834 goto done;
838 done:
839 if (!cli) {
840 return werr;
843 /* if last query */
844 if (NT_STATUS_IS_OK(status) ||
845 NT_STATUS_IS_ERR(status)) {
847 if (ctx->disable_policy_handle_cache) {
848 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
849 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
853 return werr;
856 /****************************************************************
857 ****************************************************************/
859 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
860 struct NetUserEnum *r)
862 return WERR_NOT_SUPPORTED;
865 /****************************************************************
866 ****************************************************************/
868 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
869 struct samr_DispInfoGeneral *info,
870 uint32_t *entries_read,
871 void **buffer)
873 struct NET_DISPLAY_USER *user = NULL;
874 int i;
876 user = TALLOC_ZERO_ARRAY(mem_ctx,
877 struct NET_DISPLAY_USER,
878 info->count);
879 W_ERROR_HAVE_NO_MEMORY(user);
881 for (i = 0; i < info->count; i++) {
882 user[i].usri1_name = talloc_strdup(mem_ctx,
883 info->entries[i].account_name.string);
884 user[i].usri1_comment = talloc_strdup(mem_ctx,
885 info->entries[i].description.string);
886 user[i].usri1_flags =
887 info->entries[i].acct_flags;
888 user[i].usri1_full_name = talloc_strdup(mem_ctx,
889 info->entries[i].full_name.string);
890 user[i].usri1_user_id =
891 info->entries[i].rid;
892 user[i].usri1_next_index =
893 info->entries[i].idx;
895 if (!user[i].usri1_name) {
896 return WERR_NOMEM;
900 *buffer = talloc_memdup(mem_ctx, user,
901 sizeof(struct NET_DISPLAY_USER) * info->count);
902 W_ERROR_HAVE_NO_MEMORY(*buffer);
904 *entries_read = info->count;
906 return WERR_OK;
909 /****************************************************************
910 ****************************************************************/
912 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
913 struct samr_DispInfoFull *info,
914 uint32_t *entries_read,
915 void **buffer)
917 struct NET_DISPLAY_MACHINE *machine = NULL;
918 int i;
920 machine = TALLOC_ZERO_ARRAY(mem_ctx,
921 struct NET_DISPLAY_MACHINE,
922 info->count);
923 W_ERROR_HAVE_NO_MEMORY(machine);
925 for (i = 0; i < info->count; i++) {
926 machine[i].usri2_name = talloc_strdup(mem_ctx,
927 info->entries[i].account_name.string);
928 machine[i].usri2_comment = talloc_strdup(mem_ctx,
929 info->entries[i].description.string);
930 machine[i].usri2_flags =
931 info->entries[i].acct_flags;
932 machine[i].usri2_user_id =
933 info->entries[i].rid;
934 machine[i].usri2_next_index =
935 info->entries[i].idx;
937 if (!machine[i].usri2_name) {
938 return WERR_NOMEM;
942 *buffer = talloc_memdup(mem_ctx, machine,
943 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
944 W_ERROR_HAVE_NO_MEMORY(*buffer);
946 *entries_read = info->count;
948 return WERR_OK;
951 /****************************************************************
952 ****************************************************************/
954 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
955 struct samr_DispInfoFullGroups *info,
956 uint32_t *entries_read,
957 void **buffer)
959 struct NET_DISPLAY_GROUP *group = NULL;
960 int i;
962 group = TALLOC_ZERO_ARRAY(mem_ctx,
963 struct NET_DISPLAY_GROUP,
964 info->count);
965 W_ERROR_HAVE_NO_MEMORY(group);
967 for (i = 0; i < info->count; i++) {
968 group[i].grpi3_name = talloc_strdup(mem_ctx,
969 info->entries[i].account_name.string);
970 group[i].grpi3_comment = talloc_strdup(mem_ctx,
971 info->entries[i].description.string);
972 group[i].grpi3_group_id =
973 info->entries[i].rid;
974 group[i].grpi3_attributes =
975 info->entries[i].acct_flags;
976 group[i].grpi3_next_index =
977 info->entries[i].idx;
979 if (!group[i].grpi3_name) {
980 return WERR_NOMEM;
984 *buffer = talloc_memdup(mem_ctx, group,
985 sizeof(struct NET_DISPLAY_GROUP) * info->count);
986 W_ERROR_HAVE_NO_MEMORY(*buffer);
988 *entries_read = info->count;
990 return WERR_OK;
994 /****************************************************************
995 ****************************************************************/
997 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
998 union samr_DispInfo *info,
999 uint32_t level,
1000 uint32_t *entries_read,
1001 void **buffer)
1003 switch (level) {
1004 case 1:
1005 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1006 &info->info1,
1007 entries_read,
1008 buffer);
1009 case 2:
1010 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1011 &info->info2,
1012 entries_read,
1013 buffer);
1014 case 3:
1015 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1016 &info->info3,
1017 entries_read,
1018 buffer);
1019 default:
1020 return WERR_UNKNOWN_LEVEL;
1023 return WERR_OK;
1026 /****************************************************************
1027 ****************************************************************/
1029 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1030 struct NetQueryDisplayInformation *r)
1032 struct cli_state *cli = NULL;
1033 struct rpc_pipe_client *pipe_cli = NULL;
1034 struct policy_handle connect_handle;
1035 struct dom_sid2 *domain_sid = NULL;
1036 struct policy_handle domain_handle;
1037 union samr_DispInfo info;
1039 uint32_t total_size = 0;
1040 uint32_t returned_size = 0;
1042 NTSTATUS status = NT_STATUS_OK;
1043 WERROR werr;
1045 ZERO_STRUCT(connect_handle);
1046 ZERO_STRUCT(domain_handle);
1048 switch (r->in.level) {
1049 case 1:
1050 case 2:
1051 case 3:
1052 break;
1053 default:
1054 return WERR_UNKNOWN_LEVEL;
1057 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1058 if (!W_ERROR_IS_OK(werr)) {
1059 goto done;
1062 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1063 &pipe_cli);
1064 if (!W_ERROR_IS_OK(werr)) {
1065 goto done;
1068 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1069 SAMR_ACCESS_ENUM_DOMAINS |
1070 SAMR_ACCESS_OPEN_DOMAIN,
1071 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1072 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1073 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1074 &connect_handle,
1075 &domain_handle,
1076 &domain_sid);
1077 if (!W_ERROR_IS_OK(werr)) {
1078 goto done;
1081 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1082 ctx,
1083 &domain_handle,
1084 r->in.level,
1085 r->in.idx,
1086 r->in.entries_requested,
1087 r->in.prefmaxlen,
1088 &total_size,
1089 &returned_size,
1090 &info);
1091 if (!NT_STATUS_IS_OK(status)) {
1092 werr = ntstatus_to_werror(status);
1093 goto done;
1096 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1097 r->in.level,
1098 r->out.entries_read,
1099 r->out.buffer);
1100 done:
1101 if (!cli) {
1102 return werr;
1105 /* if last query */
1106 if (NT_STATUS_IS_OK(status) ||
1107 NT_STATUS_IS_ERR(status)) {
1109 if (ctx->disable_policy_handle_cache) {
1110 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1111 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1115 return werr;
1119 /****************************************************************
1120 ****************************************************************/
1123 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1124 struct NetQueryDisplayInformation *r)
1126 return WERR_NOT_SUPPORTED;
1129 /****************************************************************
1130 ****************************************************************/
1132 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1133 struct NetUserChangePassword *r)
1135 return WERR_NOT_SUPPORTED;
1138 /****************************************************************
1139 ****************************************************************/
1141 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1142 struct NetUserChangePassword *r)
1144 return WERR_NOT_SUPPORTED;
1147 /****************************************************************
1148 ****************************************************************/
1150 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1151 struct NetUserGetInfo *r)
1153 struct cli_state *cli = NULL;
1154 struct rpc_pipe_client *pipe_cli = NULL;
1155 NTSTATUS status;
1156 WERROR werr;
1158 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1159 struct lsa_String lsa_account_name;
1160 struct dom_sid2 *domain_sid = NULL;
1161 struct samr_Ids user_rids, name_types;
1162 uint32_t num_entries = 0;
1164 ZERO_STRUCT(connect_handle);
1165 ZERO_STRUCT(domain_handle);
1166 ZERO_STRUCT(builtin_handle);
1167 ZERO_STRUCT(user_handle);
1169 if (!r->out.buffer) {
1170 return WERR_INVALID_PARAM;
1173 switch (r->in.level) {
1174 case 0:
1175 /* case 1: */
1176 case 10:
1177 case 20:
1178 case 23:
1179 break;
1180 default:
1181 werr = WERR_NOT_SUPPORTED;
1182 goto done;
1185 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1186 if (!W_ERROR_IS_OK(werr)) {
1187 goto done;
1190 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1191 &pipe_cli);
1192 if (!W_ERROR_IS_OK(werr)) {
1193 goto done;
1196 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1197 SAMR_ACCESS_ENUM_DOMAINS |
1198 SAMR_ACCESS_OPEN_DOMAIN,
1199 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1200 &connect_handle,
1201 &domain_handle,
1202 &domain_sid);
1203 if (!W_ERROR_IS_OK(werr)) {
1204 goto done;
1207 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1208 SAMR_ACCESS_ENUM_DOMAINS |
1209 SAMR_ACCESS_OPEN_DOMAIN,
1210 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1211 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1212 &connect_handle,
1213 &builtin_handle);
1214 if (!W_ERROR_IS_OK(werr)) {
1215 goto done;
1218 init_lsa_String(&lsa_account_name, r->in.user_name);
1220 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1221 &domain_handle,
1223 &lsa_account_name,
1224 &user_rids,
1225 &name_types);
1226 if (!NT_STATUS_IS_OK(status)) {
1227 werr = ntstatus_to_werror(status);
1228 goto done;
1231 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1232 domain_sid,
1233 &domain_handle,
1234 &builtin_handle,
1235 r->in.user_name,
1236 user_rids.ids[0],
1237 r->in.level,
1238 r->out.buffer,
1239 &num_entries);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 werr = ntstatus_to_werror(status);
1242 goto done;
1245 done:
1246 if (!cli) {
1247 return werr;
1250 if (is_valid_policy_hnd(&user_handle)) {
1251 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1254 if (ctx->disable_policy_handle_cache) {
1255 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1256 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1259 return werr;
1262 /****************************************************************
1263 ****************************************************************/
1265 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1266 struct NetUserGetInfo *r)
1268 return WERR_NOT_SUPPORTED;
1271 /****************************************************************
1272 ****************************************************************/
1274 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1275 struct NetUserSetInfo *r)
1277 struct cli_state *cli = NULL;
1278 struct rpc_pipe_client *pipe_cli = NULL;
1279 NTSTATUS status;
1280 WERROR werr;
1282 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1283 struct lsa_String lsa_account_name;
1284 struct dom_sid2 *domain_sid = NULL;
1285 struct samr_Ids user_rids, name_types;
1286 union samr_UserInfo user_info;
1288 struct USER_INFO_X uX;
1290 ZERO_STRUCT(connect_handle);
1291 ZERO_STRUCT(domain_handle);
1292 ZERO_STRUCT(builtin_handle);
1293 ZERO_STRUCT(user_handle);
1295 if (!r->in.buffer) {
1296 return WERR_INVALID_PARAM;
1299 switch (r->in.level) {
1300 case 0:
1301 case 1007:
1302 break;
1303 default:
1304 werr = WERR_NOT_SUPPORTED;
1305 goto done;
1308 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1309 if (!W_ERROR_IS_OK(werr)) {
1310 goto done;
1313 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1314 &pipe_cli);
1315 if (!W_ERROR_IS_OK(werr)) {
1316 goto done;
1319 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1320 SAMR_ACCESS_ENUM_DOMAINS |
1321 SAMR_ACCESS_OPEN_DOMAIN,
1322 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1323 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1324 &connect_handle,
1325 &domain_handle,
1326 &domain_sid);
1327 if (!W_ERROR_IS_OK(werr)) {
1328 goto done;
1331 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1332 SAMR_ACCESS_ENUM_DOMAINS |
1333 SAMR_ACCESS_OPEN_DOMAIN,
1334 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1335 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1336 &connect_handle,
1337 &builtin_handle);
1338 if (!W_ERROR_IS_OK(werr)) {
1339 goto done;
1342 init_lsa_String(&lsa_account_name, r->in.user_name);
1344 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1345 &domain_handle,
1347 &lsa_account_name,
1348 &user_rids,
1349 &name_types);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 werr = ntstatus_to_werror(status);
1352 goto done;
1355 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1356 &domain_handle,
1357 SAMR_USER_ACCESS_SET_ATTRIBUTES,
1358 user_rids.ids[0],
1359 &user_handle);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 werr = ntstatus_to_werror(status);
1362 goto done;
1365 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 werr = ntstatus_to_werror(status);
1368 goto done;
1371 convert_USER_INFO_X_to_samr_user_info21(&uX, &user_info.info21);
1373 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
1374 &user_handle,
1376 &user_info);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 werr = ntstatus_to_werror(status);
1379 goto done;
1382 werr = WERR_OK;
1384 done:
1385 if (!cli) {
1386 return werr;
1389 if (is_valid_policy_hnd(&user_handle)) {
1390 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1393 if (ctx->disable_policy_handle_cache) {
1394 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1395 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1396 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1399 return werr;
1402 /****************************************************************
1403 ****************************************************************/
1405 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1406 struct NetUserSetInfo *r)
1408 return WERR_NOT_SUPPORTED;
1411 /****************************************************************
1412 ****************************************************************/
1414 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1415 struct rpc_pipe_client *pipe_cli,
1416 struct policy_handle *domain_handle,
1417 struct samr_DomInfo1 *info1,
1418 struct samr_DomInfo3 *info3,
1419 struct samr_DomInfo5 *info5,
1420 struct samr_DomInfo6 *info6,
1421 struct samr_DomInfo7 *info7,
1422 struct samr_DomInfo12 *info12)
1424 NTSTATUS status;
1425 union samr_DomainInfo *dom_info = NULL;
1427 if (info1) {
1428 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1429 domain_handle,
1431 &dom_info);
1432 NT_STATUS_NOT_OK_RETURN(status);
1434 *info1 = dom_info->info1;
1437 if (info3) {
1438 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1439 domain_handle,
1441 &dom_info);
1442 NT_STATUS_NOT_OK_RETURN(status);
1444 *info3 = dom_info->info3;
1447 if (info5) {
1448 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1449 domain_handle,
1451 &dom_info);
1452 NT_STATUS_NOT_OK_RETURN(status);
1454 *info5 = dom_info->info5;
1457 if (info6) {
1458 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1459 domain_handle,
1461 &dom_info);
1462 NT_STATUS_NOT_OK_RETURN(status);
1464 *info6 = dom_info->info6;
1467 if (info7) {
1468 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1469 domain_handle,
1471 &dom_info);
1472 NT_STATUS_NOT_OK_RETURN(status);
1474 *info7 = dom_info->info7;
1477 if (info12) {
1478 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1479 domain_handle,
1481 &dom_info);
1482 NT_STATUS_NOT_OK_RETURN(status);
1484 *info12 = dom_info->info12;
1487 return NT_STATUS_OK;
1490 /****************************************************************
1491 ****************************************************************/
1493 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1494 struct rpc_pipe_client *pipe_cli,
1495 struct policy_handle *domain_handle,
1496 struct USER_MODALS_INFO_0 *info0)
1498 NTSTATUS status;
1499 struct samr_DomInfo1 dom_info1;
1500 struct samr_DomInfo3 dom_info3;
1502 ZERO_STRUCTP(info0);
1504 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1505 pipe_cli,
1506 domain_handle,
1507 &dom_info1,
1508 &dom_info3,
1509 NULL,
1510 NULL,
1511 NULL,
1512 NULL);
1513 NT_STATUS_NOT_OK_RETURN(status);
1515 info0->usrmod0_min_passwd_len =
1516 dom_info1.min_password_length;
1517 info0->usrmod0_max_passwd_age =
1518 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1519 info0->usrmod0_min_passwd_age =
1520 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
1521 info0->usrmod0_password_hist_len =
1522 dom_info1.password_history_length;
1524 info0->usrmod0_force_logoff =
1525 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
1527 return NT_STATUS_OK;
1530 /****************************************************************
1531 ****************************************************************/
1533 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
1534 struct rpc_pipe_client *pipe_cli,
1535 struct policy_handle *domain_handle,
1536 struct USER_MODALS_INFO_1 *info1)
1538 NTSTATUS status;
1539 struct samr_DomInfo6 dom_info6;
1540 struct samr_DomInfo7 dom_info7;
1542 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1543 pipe_cli,
1544 domain_handle,
1545 NULL,
1546 NULL,
1547 NULL,
1548 &dom_info6,
1549 &dom_info7,
1550 NULL);
1551 NT_STATUS_NOT_OK_RETURN(status);
1553 info1->usrmod1_primary =
1554 talloc_strdup(mem_ctx, dom_info6.primary.string);
1556 info1->usrmod1_role = dom_info7.role;
1558 return NT_STATUS_OK;
1561 /****************************************************************
1562 ****************************************************************/
1564 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
1565 struct rpc_pipe_client *pipe_cli,
1566 struct policy_handle *domain_handle,
1567 struct dom_sid *domain_sid,
1568 struct USER_MODALS_INFO_2 *info2)
1570 NTSTATUS status;
1571 struct samr_DomInfo5 dom_info5;
1573 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1574 pipe_cli,
1575 domain_handle,
1576 NULL,
1577 NULL,
1578 &dom_info5,
1579 NULL,
1580 NULL,
1581 NULL);
1582 NT_STATUS_NOT_OK_RETURN(status);
1584 info2->usrmod2_domain_name =
1585 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
1586 info2->usrmod2_domain_id =
1587 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
1589 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
1590 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
1592 return NT_STATUS_OK;
1595 /****************************************************************
1596 ****************************************************************/
1598 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
1599 struct rpc_pipe_client *pipe_cli,
1600 struct policy_handle *domain_handle,
1601 struct USER_MODALS_INFO_3 *info3)
1603 NTSTATUS status;
1604 struct samr_DomInfo12 dom_info12;
1606 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1607 pipe_cli,
1608 domain_handle,
1609 NULL,
1610 NULL,
1611 NULL,
1612 NULL,
1613 NULL,
1614 &dom_info12);
1615 NT_STATUS_NOT_OK_RETURN(status);
1617 info3->usrmod3_lockout_duration =
1618 nt_time_to_unix_abs(&dom_info12.lockout_duration);
1619 info3->usrmod3_lockout_observation_window =
1620 nt_time_to_unix_abs(&dom_info12.lockout_window);
1621 info3->usrmod3_lockout_threshold =
1622 dom_info12.lockout_threshold;
1624 return NT_STATUS_OK;
1627 /****************************************************************
1628 ****************************************************************/
1630 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
1631 struct rpc_pipe_client *pipe_cli,
1632 uint32_t level,
1633 struct policy_handle *domain_handle,
1634 struct dom_sid *domain_sid,
1635 uint8_t **buffer)
1637 NTSTATUS status;
1639 struct USER_MODALS_INFO_0 info0;
1640 struct USER_MODALS_INFO_1 info1;
1641 struct USER_MODALS_INFO_2 info2;
1642 struct USER_MODALS_INFO_3 info3;
1644 if (!buffer) {
1645 return ERROR_INSUFFICIENT_BUFFER;
1648 switch (level) {
1649 case 0:
1650 status = query_USER_MODALS_INFO_0(mem_ctx,
1651 pipe_cli,
1652 domain_handle,
1653 &info0);
1654 NT_STATUS_NOT_OK_RETURN(status);
1656 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
1657 sizeof(info0));
1658 break;
1660 case 1:
1661 status = query_USER_MODALS_INFO_1(mem_ctx,
1662 pipe_cli,
1663 domain_handle,
1664 &info1);
1665 NT_STATUS_NOT_OK_RETURN(status);
1667 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
1668 sizeof(info1));
1669 break;
1670 case 2:
1671 status = query_USER_MODALS_INFO_2(mem_ctx,
1672 pipe_cli,
1673 domain_handle,
1674 domain_sid,
1675 &info2);
1676 NT_STATUS_NOT_OK_RETURN(status);
1678 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
1679 sizeof(info2));
1680 break;
1681 case 3:
1682 status = query_USER_MODALS_INFO_3(mem_ctx,
1683 pipe_cli,
1684 domain_handle,
1685 &info3);
1686 NT_STATUS_NOT_OK_RETURN(status);
1688 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
1689 sizeof(info3));
1690 break;
1691 default:
1692 break;
1695 NT_STATUS_HAVE_NO_MEMORY(*buffer);
1697 return NT_STATUS_OK;
1700 /****************************************************************
1701 ****************************************************************/
1703 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
1704 struct NetUserModalsGet *r)
1706 struct cli_state *cli = NULL;
1707 struct rpc_pipe_client *pipe_cli = NULL;
1708 NTSTATUS status;
1709 WERROR werr;
1711 struct policy_handle connect_handle, domain_handle;
1712 struct dom_sid2 *domain_sid = NULL;
1713 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
1715 ZERO_STRUCT(connect_handle);
1716 ZERO_STRUCT(domain_handle);
1718 if (!r->out.buffer) {
1719 return WERR_INVALID_PARAM;
1722 switch (r->in.level) {
1723 case 0:
1724 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1725 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1726 break;
1727 case 1:
1728 case 2:
1729 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1730 break;
1731 case 3:
1732 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
1733 break;
1734 default:
1735 werr = WERR_UNKNOWN_LEVEL;
1736 goto done;
1739 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1740 if (!W_ERROR_IS_OK(werr)) {
1741 goto done;
1744 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1745 &pipe_cli);
1746 if (!W_ERROR_IS_OK(werr)) {
1747 goto done;
1750 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1751 SAMR_ACCESS_ENUM_DOMAINS |
1752 SAMR_ACCESS_OPEN_DOMAIN,
1753 access_mask,
1754 &connect_handle,
1755 &domain_handle,
1756 &domain_sid);
1757 if (!W_ERROR_IS_OK(werr)) {
1758 goto done;
1761 /* 0: 1 + 3 */
1762 /* 1: 6 + 7 */
1763 /* 2: 5 */
1764 /* 3: 12 (DomainInfo2) */
1766 status = query_USER_MODALS_INFO_to_buffer(ctx,
1767 pipe_cli,
1768 r->in.level,
1769 &domain_handle,
1770 domain_sid,
1771 r->out.buffer);
1772 if (!NT_STATUS_IS_OK(status)) {
1773 werr = ntstatus_to_werror(status);
1774 goto done;
1777 done:
1778 if (!cli) {
1779 return werr;
1782 if (ctx->disable_policy_handle_cache) {
1783 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1784 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1787 return werr;
1790 /****************************************************************
1791 ****************************************************************/
1793 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
1794 struct NetUserModalsGet *r)
1796 return NetUserModalsGet_r(ctx, r);
1799 /****************************************************************
1800 ****************************************************************/
1802 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1803 struct rpc_pipe_client *pipe_cli,
1804 struct policy_handle *domain_handle,
1805 struct samr_DomInfo1 *info1,
1806 struct samr_DomInfo3 *info3,
1807 struct samr_DomInfo12 *info12)
1809 NTSTATUS status;
1810 union samr_DomainInfo dom_info;
1812 if (info1) {
1814 ZERO_STRUCT(dom_info);
1816 dom_info.info1 = *info1;
1818 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1819 domain_handle,
1821 &dom_info);
1822 NT_STATUS_NOT_OK_RETURN(status);
1825 if (info3) {
1827 ZERO_STRUCT(dom_info);
1829 dom_info.info3 = *info3;
1831 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1832 domain_handle,
1834 &dom_info);
1836 NT_STATUS_NOT_OK_RETURN(status);
1839 if (info12) {
1841 ZERO_STRUCT(dom_info);
1843 dom_info.info12 = *info12;
1845 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1846 domain_handle,
1848 &dom_info);
1850 NT_STATUS_NOT_OK_RETURN(status);
1853 return NT_STATUS_OK;
1856 /****************************************************************
1857 ****************************************************************/
1859 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1860 struct rpc_pipe_client *pipe_cli,
1861 struct policy_handle *domain_handle,
1862 struct USER_MODALS_INFO_0 *info0)
1864 NTSTATUS status;
1865 struct samr_DomInfo1 dom_info_1;
1866 struct samr_DomInfo3 dom_info_3;
1868 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1869 pipe_cli,
1870 domain_handle,
1871 &dom_info_1,
1872 &dom_info_3,
1873 NULL,
1874 NULL,
1875 NULL,
1876 NULL);
1877 NT_STATUS_NOT_OK_RETURN(status);
1879 dom_info_1.min_password_length =
1880 info0->usrmod0_min_passwd_len;
1881 dom_info_1.password_history_length =
1882 info0->usrmod0_password_hist_len;
1884 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1885 info0->usrmod0_max_passwd_age);
1886 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
1887 info0->usrmod0_min_passwd_age);
1889 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
1890 info0->usrmod0_force_logoff);
1892 return set_USER_MODALS_INFO_rpc(mem_ctx,
1893 pipe_cli,
1894 domain_handle,
1895 &dom_info_1,
1896 &dom_info_3,
1897 NULL);
1900 /****************************************************************
1901 ****************************************************************/
1903 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
1904 struct rpc_pipe_client *pipe_cli,
1905 struct policy_handle *domain_handle,
1906 struct USER_MODALS_INFO_3 *info3)
1908 NTSTATUS status;
1909 struct samr_DomInfo12 dom_info_12;
1911 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1912 pipe_cli,
1913 domain_handle,
1914 NULL,
1915 NULL,
1916 NULL,
1917 NULL,
1918 NULL,
1919 &dom_info_12);
1920 NT_STATUS_NOT_OK_RETURN(status);
1922 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
1923 info3->usrmod3_lockout_duration);
1924 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
1925 info3->usrmod3_lockout_observation_window);
1926 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
1928 return set_USER_MODALS_INFO_rpc(mem_ctx,
1929 pipe_cli,
1930 domain_handle,
1931 NULL,
1932 NULL,
1933 &dom_info_12);
1936 /****************************************************************
1937 ****************************************************************/
1939 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
1940 struct rpc_pipe_client *pipe_cli,
1941 struct policy_handle *domain_handle,
1942 struct USER_MODALS_INFO_1001 *info1001)
1944 NTSTATUS status;
1945 struct samr_DomInfo1 dom_info_1;
1947 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1948 pipe_cli,
1949 domain_handle,
1950 &dom_info_1,
1951 NULL,
1952 NULL,
1953 NULL,
1954 NULL,
1955 NULL);
1956 NT_STATUS_NOT_OK_RETURN(status);
1958 dom_info_1.min_password_length =
1959 info1001->usrmod1001_min_passwd_len;
1961 return set_USER_MODALS_INFO_rpc(mem_ctx,
1962 pipe_cli,
1963 domain_handle,
1964 &dom_info_1,
1965 NULL,
1966 NULL);
1969 /****************************************************************
1970 ****************************************************************/
1972 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
1973 struct rpc_pipe_client *pipe_cli,
1974 struct policy_handle *domain_handle,
1975 struct USER_MODALS_INFO_1002 *info1002)
1977 NTSTATUS status;
1978 struct samr_DomInfo1 dom_info_1;
1980 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1981 pipe_cli,
1982 domain_handle,
1983 &dom_info_1,
1984 NULL,
1985 NULL,
1986 NULL,
1987 NULL,
1988 NULL);
1989 NT_STATUS_NOT_OK_RETURN(status);
1991 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1992 info1002->usrmod1002_max_passwd_age);
1994 return set_USER_MODALS_INFO_rpc(mem_ctx,
1995 pipe_cli,
1996 domain_handle,
1997 &dom_info_1,
1998 NULL,
1999 NULL);
2002 /****************************************************************
2003 ****************************************************************/
2005 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2006 struct rpc_pipe_client *pipe_cli,
2007 struct policy_handle *domain_handle,
2008 struct USER_MODALS_INFO_1003 *info1003)
2010 NTSTATUS status;
2011 struct samr_DomInfo1 dom_info_1;
2013 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2014 pipe_cli,
2015 domain_handle,
2016 &dom_info_1,
2017 NULL,
2018 NULL,
2019 NULL,
2020 NULL,
2021 NULL);
2022 NT_STATUS_NOT_OK_RETURN(status);
2024 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2025 info1003->usrmod1003_min_passwd_age);
2027 return set_USER_MODALS_INFO_rpc(mem_ctx,
2028 pipe_cli,
2029 domain_handle,
2030 &dom_info_1,
2031 NULL,
2032 NULL);
2035 /****************************************************************
2036 ****************************************************************/
2038 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2039 struct rpc_pipe_client *pipe_cli,
2040 struct policy_handle *domain_handle,
2041 struct USER_MODALS_INFO_1004 *info1004)
2043 NTSTATUS status;
2044 struct samr_DomInfo3 dom_info_3;
2046 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2047 pipe_cli,
2048 domain_handle,
2049 NULL,
2050 &dom_info_3,
2051 NULL,
2052 NULL,
2053 NULL,
2054 NULL);
2055 NT_STATUS_NOT_OK_RETURN(status);
2057 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2058 info1004->usrmod1004_force_logoff);
2060 return set_USER_MODALS_INFO_rpc(mem_ctx,
2061 pipe_cli,
2062 domain_handle,
2063 NULL,
2064 &dom_info_3,
2065 NULL);
2068 /****************************************************************
2069 ****************************************************************/
2071 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2072 struct rpc_pipe_client *pipe_cli,
2073 struct policy_handle *domain_handle,
2074 struct USER_MODALS_INFO_1005 *info1005)
2076 NTSTATUS status;
2077 struct samr_DomInfo1 dom_info_1;
2079 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2080 pipe_cli,
2081 domain_handle,
2082 &dom_info_1,
2083 NULL,
2084 NULL,
2085 NULL,
2086 NULL,
2087 NULL);
2088 NT_STATUS_NOT_OK_RETURN(status);
2090 dom_info_1.password_history_length =
2091 info1005->usrmod1005_password_hist_len;
2093 return set_USER_MODALS_INFO_rpc(mem_ctx,
2094 pipe_cli,
2095 domain_handle,
2096 &dom_info_1,
2097 NULL,
2098 NULL);
2101 /****************************************************************
2102 ****************************************************************/
2104 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2105 struct rpc_pipe_client *pipe_cli,
2106 uint32_t level,
2107 struct policy_handle *domain_handle,
2108 struct dom_sid *domain_sid,
2109 uint8_t *buffer)
2111 struct USER_MODALS_INFO_0 *info0;
2112 struct USER_MODALS_INFO_3 *info3;
2113 struct USER_MODALS_INFO_1001 *info1001;
2114 struct USER_MODALS_INFO_1002 *info1002;
2115 struct USER_MODALS_INFO_1003 *info1003;
2116 struct USER_MODALS_INFO_1004 *info1004;
2117 struct USER_MODALS_INFO_1005 *info1005;
2119 if (!buffer) {
2120 return ERROR_INSUFFICIENT_BUFFER;
2123 switch (level) {
2124 case 0:
2125 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2126 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2127 pipe_cli,
2128 domain_handle,
2129 info0);
2130 case 3:
2131 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2132 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2133 pipe_cli,
2134 domain_handle,
2135 info3);
2136 case 1001:
2137 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2138 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2139 pipe_cli,
2140 domain_handle,
2141 info1001);
2142 case 1002:
2143 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2144 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2145 pipe_cli,
2146 domain_handle,
2147 info1002);
2148 case 1003:
2149 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2150 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2151 pipe_cli,
2152 domain_handle,
2153 info1003);
2154 case 1004:
2155 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2156 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2157 pipe_cli,
2158 domain_handle,
2159 info1004);
2160 case 1005:
2161 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2162 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2163 pipe_cli,
2164 domain_handle,
2165 info1005);
2167 default:
2168 break;
2171 return NT_STATUS_OK;
2174 /****************************************************************
2175 ****************************************************************/
2177 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2178 struct NetUserModalsSet *r)
2180 struct cli_state *cli = NULL;
2181 struct rpc_pipe_client *pipe_cli = NULL;
2182 NTSTATUS status;
2183 WERROR werr;
2185 struct policy_handle connect_handle, domain_handle;
2186 struct dom_sid2 *domain_sid = NULL;
2187 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2189 ZERO_STRUCT(connect_handle);
2190 ZERO_STRUCT(domain_handle);
2192 if (!r->in.buffer) {
2193 return WERR_INVALID_PARAM;
2196 switch (r->in.level) {
2197 case 0:
2198 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2199 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2200 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2201 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2202 break;
2203 case 3:
2204 case 1001:
2205 case 1002:
2206 case 1003:
2207 case 1005:
2208 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2209 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2210 break;
2211 case 1004:
2212 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2213 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2214 break;
2215 case 1:
2216 case 2:
2217 case 1006:
2218 case 1007:
2219 werr = WERR_NOT_SUPPORTED;
2220 break;
2221 default:
2222 werr = WERR_UNKNOWN_LEVEL;
2223 goto done;
2226 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
2227 if (!W_ERROR_IS_OK(werr)) {
2228 goto done;
2231 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
2232 &pipe_cli);
2233 if (!W_ERROR_IS_OK(werr)) {
2234 goto done;
2237 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2238 SAMR_ACCESS_ENUM_DOMAINS |
2239 SAMR_ACCESS_OPEN_DOMAIN,
2240 access_mask,
2241 &connect_handle,
2242 &domain_handle,
2243 &domain_sid);
2244 if (!W_ERROR_IS_OK(werr)) {
2245 goto done;
2248 status = set_USER_MODALS_INFO_buffer(ctx,
2249 pipe_cli,
2250 r->in.level,
2251 &domain_handle,
2252 domain_sid,
2253 r->in.buffer);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 werr = ntstatus_to_werror(status);
2256 goto done;
2259 done:
2260 if (!cli) {
2261 return werr;
2264 if (ctx->disable_policy_handle_cache) {
2265 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2266 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2269 return werr;
2272 /****************************************************************
2273 ****************************************************************/
2275 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2276 struct NetUserModalsSet *r)
2278 return NetUserModalsSet_r(ctx, r);