netapi: process level 1003 in construct_USER_INFO_X as well.
[Samba.git] / source / lib / netapi / user.c
blob97eb9d8002db70e47db384e654faf593fb10d017
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_1003 *u1003 = NULL;
115 struct USER_INFO_1007 *u1007 = NULL;
117 if (!buffer || !uX) {
118 return NT_STATUS_INVALID_PARAMETER;
121 ZERO_STRUCTP(uX);
123 switch (level) {
124 case 0:
125 u0 = (struct USER_INFO_0 *)buffer;
126 uX->usriX_name = u0->usri0_name;
127 break;
128 case 1:
129 u1 = (struct USER_INFO_1 *)buffer;
130 uX->usriX_name = u1->usri1_name;
131 uX->usriX_password = u1->usri1_password;
132 uX->usriX_password_age = u1->usri1_password_age;
133 uX->usriX_priv = u1->usri1_priv;
134 uX->usriX_home_dir = u1->usri1_home_dir;
135 uX->usriX_comment = u1->usri1_comment;
136 uX->usriX_flags = u1->usri1_flags;
137 uX->usriX_script_path = u1->usri1_script_path;
138 break;
139 case 2:
140 u2 = (struct USER_INFO_2 *)buffer;
141 uX->usriX_name = u2->usri2_name;
142 uX->usriX_password = u2->usri2_password;
143 uX->usriX_password_age = u2->usri2_password_age;
144 uX->usriX_priv = u2->usri2_priv;
145 uX->usriX_home_dir = u2->usri2_home_dir;
146 uX->usriX_comment = u2->usri2_comment;
147 uX->usriX_flags = u2->usri2_flags;
148 uX->usriX_script_path = u2->usri2_script_path;
149 uX->usriX_auth_flags = u2->usri2_auth_flags;
150 uX->usriX_full_name = u2->usri2_full_name;
151 uX->usriX_usr_comment = u2->usri2_usr_comment;
152 uX->usriX_parms = u2->usri2_parms;
153 uX->usriX_workstations = u2->usri2_workstations;
154 uX->usriX_last_logon = u2->usri2_last_logon;
155 uX->usriX_last_logoff = u2->usri2_last_logoff;
156 uX->usriX_acct_expires = u2->usri2_acct_expires;
157 uX->usriX_max_storage = u2->usri2_max_storage;
158 uX->usriX_units_per_week= u2->usri2_units_per_week;
159 uX->usriX_logon_hours = u2->usri2_logon_hours;
160 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
161 uX->usriX_num_logons = u2->usri2_num_logons;
162 uX->usriX_logon_server = u2->usri2_logon_server;
163 uX->usriX_country_code = u2->usri2_country_code;
164 uX->usriX_code_page = u2->usri2_code_page;
165 break;
166 case 1003:
167 u1003 = (struct USER_INFO_1003 *)buffer;
168 uX->usriX_password = u1003->usri1003_password;
169 break;
170 case 1007:
171 u1007 = (struct USER_INFO_1007 *)buffer;
172 uX->usriX_comment = u1007->usri1007_comment;
173 break;
174 case 3:
175 case 4:
176 default:
177 return NT_STATUS_INVALID_INFO_CLASS;
180 return NT_STATUS_OK;
183 /****************************************************************
184 ****************************************************************/
186 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
187 struct rpc_pipe_client *pipe_cli,
188 DATA_BLOB *session_key,
189 struct policy_handle *user_handle,
190 struct USER_INFO_X *uX)
192 union samr_UserInfo user_info;
193 struct samr_UserInfo21 info21;
194 NTSTATUS status;
196 if (!uX) {
197 return NT_STATUS_INVALID_PARAMETER;
200 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
202 ZERO_STRUCT(user_info);
204 if (uX->usriX_password) {
206 user_info.info25.info = info21;
208 init_samr_CryptPasswordEx(uX->usriX_password,
209 session_key,
210 &user_info.info25.password);
212 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
213 user_handle,
215 &user_info);
217 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
219 user_info.info23.info = info21;
221 init_samr_CryptPassword(uX->usriX_password,
222 session_key,
223 &user_info.info23.password);
225 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
226 user_handle,
228 &user_info);
230 } else {
232 user_info.info21 = info21;
234 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
235 user_handle,
237 &user_info);
240 return status;
243 /****************************************************************
244 ****************************************************************/
246 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
247 struct NetUserAdd *r)
249 struct cli_state *cli = NULL;
250 struct rpc_pipe_client *pipe_cli = NULL;
251 NTSTATUS status;
252 WERROR werr;
253 POLICY_HND connect_handle, domain_handle, user_handle;
254 struct lsa_String lsa_account_name;
255 struct dom_sid2 *domain_sid = NULL;
256 union samr_UserInfo *user_info = NULL;
257 struct samr_PwInfo pw_info;
258 uint32_t access_granted = 0;
259 uint32_t rid = 0;
260 struct USER_INFO_X uX;
262 ZERO_STRUCT(connect_handle);
263 ZERO_STRUCT(domain_handle);
264 ZERO_STRUCT(user_handle);
266 if (!r->in.buffer) {
267 return WERR_INVALID_PARAM;
270 switch (r->in.level) {
271 case 1:
272 break;
273 case 2:
274 case 3:
275 case 4:
276 default:
277 werr = WERR_NOT_SUPPORTED;
278 goto done;
281 werr = libnetapi_open_pipe(ctx, r->in.server_name,
282 &ndr_table_samr.syntax_id,
283 &cli,
284 &pipe_cli);
285 if (!W_ERROR_IS_OK(werr)) {
286 goto done;
289 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
290 if (!NT_STATUS_IS_OK(status)) {
291 werr = ntstatus_to_werror(status);
292 goto done;
295 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
296 SAMR_ACCESS_ENUM_DOMAINS |
297 SAMR_ACCESS_OPEN_DOMAIN,
298 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
299 SAMR_DOMAIN_ACCESS_CREATE_USER |
300 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
301 &connect_handle,
302 &domain_handle,
303 &domain_sid);
304 if (!W_ERROR_IS_OK(werr)) {
305 goto done;
308 init_lsa_String(&lsa_account_name, uX.usriX_name);
310 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
311 &domain_handle,
312 &lsa_account_name,
313 ACB_NORMAL,
314 SEC_STD_WRITE_DAC |
315 SEC_STD_DELETE |
316 SAMR_USER_ACCESS_SET_PASSWORD |
317 SAMR_USER_ACCESS_SET_ATTRIBUTES |
318 SAMR_USER_ACCESS_GET_ATTRIBUTES,
319 &user_handle,
320 &access_granted,
321 &rid);
322 if (!NT_STATUS_IS_OK(status)) {
323 werr = ntstatus_to_werror(status);
324 goto done;
327 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
328 &user_handle,
330 &user_info);
331 if (!NT_STATUS_IS_OK(status)) {
332 werr = ntstatus_to_werror(status);
333 goto done;
336 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
337 werr = WERR_INVALID_PARAM;
338 goto done;
341 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
342 &user_handle,
343 &pw_info);
344 if (!NT_STATUS_IS_OK(status)) {
345 werr = ntstatus_to_werror(status);
346 goto done;
349 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
350 &cli->user_session_key,
351 &user_handle,
352 &uX);
353 if (!NT_STATUS_IS_OK(status)) {
354 werr = ntstatus_to_werror(status);
355 goto failed;
358 werr = WERR_OK;
359 goto done;
361 failed:
362 rpccli_samr_DeleteUser(pipe_cli, ctx,
363 &user_handle);
365 done:
366 if (!cli) {
367 return werr;
370 if (is_valid_policy_hnd(&user_handle)) {
371 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
374 if (ctx->disable_policy_handle_cache) {
375 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
376 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
379 return werr;
382 /****************************************************************
383 ****************************************************************/
385 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
386 struct NetUserAdd *r)
388 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
391 /****************************************************************
392 ****************************************************************/
394 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
395 struct NetUserDel *r)
397 struct cli_state *cli = NULL;
398 struct rpc_pipe_client *pipe_cli = NULL;
399 NTSTATUS status;
400 WERROR werr;
401 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
402 struct lsa_String lsa_account_name;
403 struct samr_Ids user_rids, name_types;
404 struct dom_sid2 *domain_sid = NULL;
405 struct dom_sid2 user_sid;
407 ZERO_STRUCT(connect_handle);
408 ZERO_STRUCT(builtin_handle);
409 ZERO_STRUCT(domain_handle);
410 ZERO_STRUCT(user_handle);
412 werr = libnetapi_open_pipe(ctx, r->in.server_name,
413 &ndr_table_samr.syntax_id,
414 &cli,
415 &pipe_cli);
417 if (!W_ERROR_IS_OK(werr)) {
418 goto done;
421 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
422 SAMR_ACCESS_ENUM_DOMAINS |
423 SAMR_ACCESS_OPEN_DOMAIN,
424 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
425 &connect_handle,
426 &domain_handle,
427 &domain_sid);
428 if (!W_ERROR_IS_OK(werr)) {
429 goto done;
432 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
433 &connect_handle,
434 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
435 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
436 &builtin_handle);
437 if (!NT_STATUS_IS_OK(status)) {
438 werr = ntstatus_to_werror(status);
439 goto done;
442 init_lsa_String(&lsa_account_name, r->in.user_name);
444 status = rpccli_samr_LookupNames(pipe_cli, ctx,
445 &domain_handle,
447 &lsa_account_name,
448 &user_rids,
449 &name_types);
450 if (!NT_STATUS_IS_OK(status)) {
451 werr = ntstatus_to_werror(status);
452 goto done;
455 status = rpccli_samr_OpenUser(pipe_cli, ctx,
456 &domain_handle,
457 STD_RIGHT_DELETE_ACCESS,
458 user_rids.ids[0],
459 &user_handle);
460 if (!NT_STATUS_IS_OK(status)) {
461 werr = ntstatus_to_werror(status);
462 goto done;
465 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
467 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
468 &builtin_handle,
469 &user_sid);
470 if (!NT_STATUS_IS_OK(status)) {
471 werr = ntstatus_to_werror(status);
472 goto done;
475 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
476 &user_handle);
477 if (!NT_STATUS_IS_OK(status)) {
478 werr = ntstatus_to_werror(status);
479 goto done;
482 werr = WERR_OK;
484 done:
485 if (!cli) {
486 return werr;
489 if (is_valid_policy_hnd(&user_handle)) {
490 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
493 if (ctx->disable_policy_handle_cache) {
494 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
495 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
496 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
499 return werr;
502 /****************************************************************
503 ****************************************************************/
505 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
506 struct NetUserDel *r)
508 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
511 /****************************************************************
512 ****************************************************************/
514 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
515 struct rpc_pipe_client *pipe_cli,
516 struct policy_handle *domain_handle,
517 struct policy_handle *builtin_handle,
518 const char *user_name,
519 uint32_t rid,
520 uint32_t level,
521 struct samr_UserInfo21 **info21,
522 struct sec_desc_buf **sec_desc)
524 NTSTATUS status;
526 struct policy_handle user_handle;
527 union samr_UserInfo *user_info = NULL;
528 struct samr_RidWithAttributeArray *rid_array = NULL;
529 uint32_t access_mask = SEC_STD_READ_CONTROL |
530 SAMR_USER_ACCESS_GET_ATTRIBUTES |
531 SAMR_USER_ACCESS_GET_NAME_ETC;
533 ZERO_STRUCT(user_handle);
535 switch (level) {
536 case 0:
537 case 1:
538 case 2:
539 case 3:
540 case 10:
541 case 11:
542 case 20:
543 case 23:
544 break;
545 default:
546 return NT_STATUS_INVALID_LEVEL;
549 if (level == 0) {
550 return NT_STATUS_OK;
553 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
554 domain_handle,
555 access_mask,
556 rid,
557 &user_handle);
558 if (!NT_STATUS_IS_OK(status)) {
559 goto done;
562 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
563 &user_handle,
565 &user_info);
566 if (!NT_STATUS_IS_OK(status)) {
567 goto done;
570 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
571 &user_handle,
572 SECINFO_DACL,
573 sec_desc);
574 if (!NT_STATUS_IS_OK(status)) {
575 goto done;
578 if (level == 1) {
579 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
580 &user_handle,
581 &rid_array);
582 if (!NT_STATUS_IS_OK(status)) {
583 goto done;
586 #if 0
587 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
588 &builtin_handle,
589 &sids,
590 &rids);
591 if (!NT_STATUS_IS_OK(status)) {
592 goto done;
594 #endif
597 *info21 = &user_info->info21;
599 done:
600 if (is_valid_policy_hnd(&user_handle)) {
601 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
604 return status;
607 /****************************************************************
608 ****************************************************************/
610 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
611 struct rpc_pipe_client *pipe_cli,
612 struct dom_sid *domain_sid,
613 struct policy_handle *domain_handle,
614 struct policy_handle *builtin_handle,
615 const char *user_name,
616 uint32_t rid,
617 uint32_t level,
618 uint8_t **buffer,
619 uint32_t *num_entries)
621 NTSTATUS status;
623 struct samr_UserInfo21 *info21 = NULL;
624 struct sec_desc_buf *sec_desc = NULL;
625 struct dom_sid sid;
627 struct USER_INFO_0 info0;
628 struct USER_INFO_10 info10;
629 struct USER_INFO_20 info20;
630 struct USER_INFO_23 info23;
632 switch (level) {
633 case 0:
634 case 1:
635 case 2:
636 case 3:
637 case 10:
638 case 11:
639 case 20:
640 case 23:
641 break;
642 default:
643 return NT_STATUS_INVALID_LEVEL;
646 if (level == 0) {
647 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
648 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
650 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
651 (struct USER_INFO_0 **)buffer, num_entries);
653 return NT_STATUS_OK;
656 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
657 domain_handle,
658 builtin_handle,
659 user_name,
660 rid,
661 level,
662 &info21,
663 &sec_desc);
665 if (!NT_STATUS_IS_OK(status)) {
666 goto done;
669 switch (level) {
670 case 10:
671 info10.usri10_name = talloc_strdup(mem_ctx, user_name);
672 NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
674 info10.usri10_comment = talloc_strdup(mem_ctx,
675 info21->description.string);
677 info10.usri10_full_name = talloc_strdup(mem_ctx,
678 info21->full_name.string);
680 info10.usri10_usr_comment = talloc_strdup(mem_ctx,
681 info21->comment.string);
683 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
684 (struct USER_INFO_10 **)buffer, num_entries);
686 break;
688 case 20:
689 info20.usri20_name = talloc_strdup(mem_ctx, user_name);
690 NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
692 info20.usri20_comment = talloc_strdup(mem_ctx,
693 info21->description.string);
695 info20.usri20_full_name = talloc_strdup(mem_ctx,
696 info21->full_name.string);
698 info20.usri20_flags = info21->acct_flags;
699 info20.usri20_user_id = rid;
701 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
702 (struct USER_INFO_20 **)buffer, num_entries);
704 break;
705 case 23:
706 info23.usri23_name = talloc_strdup(mem_ctx, user_name);
707 NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
709 info23.usri23_comment = talloc_strdup(mem_ctx,
710 info21->description.string);
712 info23.usri23_full_name = talloc_strdup(mem_ctx,
713 info21->full_name.string);
715 info23.usri23_flags = info21->acct_flags;
717 if (!sid_compose(&sid, domain_sid, rid)) {
718 return NT_STATUS_NO_MEMORY;
721 info23.usri23_user_sid =
722 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
724 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
725 (struct USER_INFO_23 **)buffer, num_entries);
726 break;
729 done:
730 return status;
733 /****************************************************************
734 ****************************************************************/
736 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
737 struct NetUserEnum *r)
739 struct cli_state *cli = NULL;
740 struct rpc_pipe_client *pipe_cli = NULL;
741 struct policy_handle connect_handle;
742 struct dom_sid2 *domain_sid = NULL;
743 struct policy_handle domain_handle;
744 struct samr_SamArray *sam = NULL;
745 uint32_t filter = ACB_NORMAL;
746 int i;
747 uint32_t entries_read = 0;
749 NTSTATUS status = NT_STATUS_OK;
750 WERROR werr;
752 ZERO_STRUCT(connect_handle);
753 ZERO_STRUCT(domain_handle);
755 if (!r->out.buffer) {
756 return WERR_INVALID_PARAM;
759 *r->out.buffer = NULL;
760 *r->out.entries_read = 0;
762 switch (r->in.level) {
763 case 0:
764 case 10:
765 case 20:
766 case 23:
767 break;
768 case 1:
769 case 2:
770 case 3:
771 case 11:
772 default:
773 return WERR_NOT_SUPPORTED;
776 werr = libnetapi_open_pipe(ctx, r->in.server_name,
777 &ndr_table_samr.syntax_id,
778 &cli,
779 &pipe_cli);
780 if (!W_ERROR_IS_OK(werr)) {
781 goto done;
784 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
785 SAMR_ACCESS_ENUM_DOMAINS |
786 SAMR_ACCESS_OPEN_DOMAIN,
787 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
788 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
789 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
790 &connect_handle,
791 &domain_handle,
792 &domain_sid);
793 if (!W_ERROR_IS_OK(werr)) {
794 goto done;
797 switch (r->in.filter) {
798 case FILTER_NORMAL_ACCOUNT:
799 filter = ACB_NORMAL;
800 break;
801 case FILTER_TEMP_DUPLICATE_ACCOUNT:
802 filter = ACB_TEMPDUP;
803 break;
804 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
805 filter = ACB_DOMTRUST;
806 break;
807 case FILTER_WORKSTATION_TRUST_ACCOUNT:
808 filter = ACB_WSTRUST;
809 break;
810 case FILTER_SERVER_TRUST_ACCOUNT:
811 filter = ACB_SVRTRUST;
812 break;
813 default:
814 break;
817 status = rpccli_samr_EnumDomainUsers(pipe_cli,
818 ctx,
819 &domain_handle,
820 r->in.resume_handle,
821 filter,
822 &sam,
823 r->in.prefmaxlen,
824 &entries_read);
825 werr = ntstatus_to_werror(status);
826 if (NT_STATUS_IS_ERR(status)) {
827 goto done;
830 for (i=0; i < sam->count; i++) {
832 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
833 domain_sid,
834 &domain_handle,
835 NULL, /*&builtin_handle, */
836 sam->entries[i].name.string,
837 sam->entries[i].idx,
838 r->in.level,
839 r->out.buffer,
840 r->out.entries_read);
841 if (!NT_STATUS_IS_OK(status)) {
842 werr = ntstatus_to_werror(status);
843 goto done;
847 done:
848 if (!cli) {
849 return werr;
852 /* if last query */
853 if (NT_STATUS_IS_OK(status) ||
854 NT_STATUS_IS_ERR(status)) {
856 if (ctx->disable_policy_handle_cache) {
857 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
858 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
862 return werr;
865 /****************************************************************
866 ****************************************************************/
868 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
869 struct NetUserEnum *r)
871 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
874 /****************************************************************
875 ****************************************************************/
877 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
878 struct samr_DispInfoGeneral *info,
879 uint32_t *entries_read,
880 void **buffer)
882 struct NET_DISPLAY_USER *user = NULL;
883 int i;
885 user = TALLOC_ZERO_ARRAY(mem_ctx,
886 struct NET_DISPLAY_USER,
887 info->count);
888 W_ERROR_HAVE_NO_MEMORY(user);
890 for (i = 0; i < info->count; i++) {
891 user[i].usri1_name = talloc_strdup(mem_ctx,
892 info->entries[i].account_name.string);
893 user[i].usri1_comment = talloc_strdup(mem_ctx,
894 info->entries[i].description.string);
895 user[i].usri1_flags =
896 info->entries[i].acct_flags;
897 user[i].usri1_full_name = talloc_strdup(mem_ctx,
898 info->entries[i].full_name.string);
899 user[i].usri1_user_id =
900 info->entries[i].rid;
901 user[i].usri1_next_index =
902 info->entries[i].idx;
904 if (!user[i].usri1_name) {
905 return WERR_NOMEM;
909 *buffer = talloc_memdup(mem_ctx, user,
910 sizeof(struct NET_DISPLAY_USER) * info->count);
911 W_ERROR_HAVE_NO_MEMORY(*buffer);
913 *entries_read = info->count;
915 return WERR_OK;
918 /****************************************************************
919 ****************************************************************/
921 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
922 struct samr_DispInfoFull *info,
923 uint32_t *entries_read,
924 void **buffer)
926 struct NET_DISPLAY_MACHINE *machine = NULL;
927 int i;
929 machine = TALLOC_ZERO_ARRAY(mem_ctx,
930 struct NET_DISPLAY_MACHINE,
931 info->count);
932 W_ERROR_HAVE_NO_MEMORY(machine);
934 for (i = 0; i < info->count; i++) {
935 machine[i].usri2_name = talloc_strdup(mem_ctx,
936 info->entries[i].account_name.string);
937 machine[i].usri2_comment = talloc_strdup(mem_ctx,
938 info->entries[i].description.string);
939 machine[i].usri2_flags =
940 info->entries[i].acct_flags;
941 machine[i].usri2_user_id =
942 info->entries[i].rid;
943 machine[i].usri2_next_index =
944 info->entries[i].idx;
946 if (!machine[i].usri2_name) {
947 return WERR_NOMEM;
951 *buffer = talloc_memdup(mem_ctx, machine,
952 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
953 W_ERROR_HAVE_NO_MEMORY(*buffer);
955 *entries_read = info->count;
957 return WERR_OK;
960 /****************************************************************
961 ****************************************************************/
963 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
964 struct samr_DispInfoFullGroups *info,
965 uint32_t *entries_read,
966 void **buffer)
968 struct NET_DISPLAY_GROUP *group = NULL;
969 int i;
971 group = TALLOC_ZERO_ARRAY(mem_ctx,
972 struct NET_DISPLAY_GROUP,
973 info->count);
974 W_ERROR_HAVE_NO_MEMORY(group);
976 for (i = 0; i < info->count; i++) {
977 group[i].grpi3_name = talloc_strdup(mem_ctx,
978 info->entries[i].account_name.string);
979 group[i].grpi3_comment = talloc_strdup(mem_ctx,
980 info->entries[i].description.string);
981 group[i].grpi3_group_id =
982 info->entries[i].rid;
983 group[i].grpi3_attributes =
984 info->entries[i].acct_flags;
985 group[i].grpi3_next_index =
986 info->entries[i].idx;
988 if (!group[i].grpi3_name) {
989 return WERR_NOMEM;
993 *buffer = talloc_memdup(mem_ctx, group,
994 sizeof(struct NET_DISPLAY_GROUP) * info->count);
995 W_ERROR_HAVE_NO_MEMORY(*buffer);
997 *entries_read = info->count;
999 return WERR_OK;
1003 /****************************************************************
1004 ****************************************************************/
1006 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1007 union samr_DispInfo *info,
1008 uint32_t level,
1009 uint32_t *entries_read,
1010 void **buffer)
1012 switch (level) {
1013 case 1:
1014 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1015 &info->info1,
1016 entries_read,
1017 buffer);
1018 case 2:
1019 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1020 &info->info2,
1021 entries_read,
1022 buffer);
1023 case 3:
1024 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1025 &info->info3,
1026 entries_read,
1027 buffer);
1028 default:
1029 return WERR_UNKNOWN_LEVEL;
1032 return WERR_OK;
1035 /****************************************************************
1036 ****************************************************************/
1038 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1039 struct NetQueryDisplayInformation *r)
1041 struct cli_state *cli = NULL;
1042 struct rpc_pipe_client *pipe_cli = NULL;
1043 struct policy_handle connect_handle;
1044 struct dom_sid2 *domain_sid = NULL;
1045 struct policy_handle domain_handle;
1046 union samr_DispInfo info;
1048 uint32_t total_size = 0;
1049 uint32_t returned_size = 0;
1051 NTSTATUS status = NT_STATUS_OK;
1052 WERROR werr;
1054 ZERO_STRUCT(connect_handle);
1055 ZERO_STRUCT(domain_handle);
1057 switch (r->in.level) {
1058 case 1:
1059 case 2:
1060 case 3:
1061 break;
1062 default:
1063 return WERR_UNKNOWN_LEVEL;
1066 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1067 &ndr_table_samr.syntax_id,
1068 &cli,
1069 &pipe_cli);
1070 if (!W_ERROR_IS_OK(werr)) {
1071 goto done;
1074 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1075 SAMR_ACCESS_ENUM_DOMAINS |
1076 SAMR_ACCESS_OPEN_DOMAIN,
1077 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1078 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1079 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1080 &connect_handle,
1081 &domain_handle,
1082 &domain_sid);
1083 if (!W_ERROR_IS_OK(werr)) {
1084 goto done;
1087 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1088 ctx,
1089 &domain_handle,
1090 r->in.level,
1091 r->in.idx,
1092 r->in.entries_requested,
1093 r->in.prefmaxlen,
1094 &total_size,
1095 &returned_size,
1096 &info);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 werr = ntstatus_to_werror(status);
1099 goto done;
1102 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1103 r->in.level,
1104 r->out.entries_read,
1105 r->out.buffer);
1106 done:
1107 if (!cli) {
1108 return werr;
1111 /* if last query */
1112 if (NT_STATUS_IS_OK(status) ||
1113 NT_STATUS_IS_ERR(status)) {
1115 if (ctx->disable_policy_handle_cache) {
1116 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1117 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1121 return werr;
1125 /****************************************************************
1126 ****************************************************************/
1129 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1130 struct NetQueryDisplayInformation *r)
1132 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1135 /****************************************************************
1136 ****************************************************************/
1138 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1139 struct NetUserChangePassword *r)
1141 return WERR_NOT_SUPPORTED;
1144 /****************************************************************
1145 ****************************************************************/
1147 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1148 struct NetUserChangePassword *r)
1150 return WERR_NOT_SUPPORTED;
1153 /****************************************************************
1154 ****************************************************************/
1156 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1157 struct NetUserGetInfo *r)
1159 struct cli_state *cli = NULL;
1160 struct rpc_pipe_client *pipe_cli = NULL;
1161 NTSTATUS status;
1162 WERROR werr;
1164 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1165 struct lsa_String lsa_account_name;
1166 struct dom_sid2 *domain_sid = NULL;
1167 struct samr_Ids user_rids, name_types;
1168 uint32_t num_entries = 0;
1170 ZERO_STRUCT(connect_handle);
1171 ZERO_STRUCT(domain_handle);
1172 ZERO_STRUCT(builtin_handle);
1173 ZERO_STRUCT(user_handle);
1175 if (!r->out.buffer) {
1176 return WERR_INVALID_PARAM;
1179 switch (r->in.level) {
1180 case 0:
1181 /* case 1: */
1182 case 10:
1183 case 20:
1184 case 23:
1185 break;
1186 default:
1187 werr = WERR_NOT_SUPPORTED;
1188 goto done;
1191 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1192 &ndr_table_samr.syntax_id,
1193 &cli,
1194 &pipe_cli);
1195 if (!W_ERROR_IS_OK(werr)) {
1196 goto done;
1199 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1200 SAMR_ACCESS_ENUM_DOMAINS |
1201 SAMR_ACCESS_OPEN_DOMAIN,
1202 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1203 &connect_handle,
1204 &domain_handle,
1205 &domain_sid);
1206 if (!W_ERROR_IS_OK(werr)) {
1207 goto done;
1210 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1211 SAMR_ACCESS_ENUM_DOMAINS |
1212 SAMR_ACCESS_OPEN_DOMAIN,
1213 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1214 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1215 &connect_handle,
1216 &builtin_handle);
1217 if (!W_ERROR_IS_OK(werr)) {
1218 goto done;
1221 init_lsa_String(&lsa_account_name, r->in.user_name);
1223 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1224 &domain_handle,
1226 &lsa_account_name,
1227 &user_rids,
1228 &name_types);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 werr = ntstatus_to_werror(status);
1231 goto done;
1234 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1235 domain_sid,
1236 &domain_handle,
1237 &builtin_handle,
1238 r->in.user_name,
1239 user_rids.ids[0],
1240 r->in.level,
1241 r->out.buffer,
1242 &num_entries);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 werr = ntstatus_to_werror(status);
1245 goto done;
1248 done:
1249 if (!cli) {
1250 return werr;
1253 if (is_valid_policy_hnd(&user_handle)) {
1254 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1257 if (ctx->disable_policy_handle_cache) {
1258 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1259 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1262 return werr;
1265 /****************************************************************
1266 ****************************************************************/
1268 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1269 struct NetUserGetInfo *r)
1271 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1274 /****************************************************************
1275 ****************************************************************/
1277 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1278 struct NetUserSetInfo *r)
1280 struct cli_state *cli = NULL;
1281 struct rpc_pipe_client *pipe_cli = NULL;
1282 NTSTATUS status;
1283 WERROR werr;
1285 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1286 struct lsa_String lsa_account_name;
1287 struct dom_sid2 *domain_sid = NULL;
1288 struct samr_Ids user_rids, name_types;
1289 union samr_UserInfo user_info;
1291 struct USER_INFO_X uX;
1293 ZERO_STRUCT(connect_handle);
1294 ZERO_STRUCT(domain_handle);
1295 ZERO_STRUCT(builtin_handle);
1296 ZERO_STRUCT(user_handle);
1298 if (!r->in.buffer) {
1299 return WERR_INVALID_PARAM;
1302 switch (r->in.level) {
1303 case 0:
1304 case 1007:
1305 break;
1306 default:
1307 werr = WERR_NOT_SUPPORTED;
1308 goto done;
1311 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1312 &ndr_table_samr.syntax_id,
1313 &cli,
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 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
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_pipe(ctx, r->in.server_name,
1740 &ndr_table_samr.syntax_id,
1741 &cli,
1742 &pipe_cli);
1743 if (!W_ERROR_IS_OK(werr)) {
1744 goto done;
1747 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1748 SAMR_ACCESS_ENUM_DOMAINS |
1749 SAMR_ACCESS_OPEN_DOMAIN,
1750 access_mask,
1751 &connect_handle,
1752 &domain_handle,
1753 &domain_sid);
1754 if (!W_ERROR_IS_OK(werr)) {
1755 goto done;
1758 /* 0: 1 + 3 */
1759 /* 1: 6 + 7 */
1760 /* 2: 5 */
1761 /* 3: 12 (DomainInfo2) */
1763 status = query_USER_MODALS_INFO_to_buffer(ctx,
1764 pipe_cli,
1765 r->in.level,
1766 &domain_handle,
1767 domain_sid,
1768 r->out.buffer);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 werr = ntstatus_to_werror(status);
1771 goto done;
1774 done:
1775 if (!cli) {
1776 return werr;
1779 if (ctx->disable_policy_handle_cache) {
1780 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1781 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1784 return werr;
1787 /****************************************************************
1788 ****************************************************************/
1790 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
1791 struct NetUserModalsGet *r)
1793 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
1796 /****************************************************************
1797 ****************************************************************/
1799 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1800 struct rpc_pipe_client *pipe_cli,
1801 struct policy_handle *domain_handle,
1802 struct samr_DomInfo1 *info1,
1803 struct samr_DomInfo3 *info3,
1804 struct samr_DomInfo12 *info12)
1806 NTSTATUS status;
1807 union samr_DomainInfo dom_info;
1809 if (info1) {
1811 ZERO_STRUCT(dom_info);
1813 dom_info.info1 = *info1;
1815 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1816 domain_handle,
1818 &dom_info);
1819 NT_STATUS_NOT_OK_RETURN(status);
1822 if (info3) {
1824 ZERO_STRUCT(dom_info);
1826 dom_info.info3 = *info3;
1828 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1829 domain_handle,
1831 &dom_info);
1833 NT_STATUS_NOT_OK_RETURN(status);
1836 if (info12) {
1838 ZERO_STRUCT(dom_info);
1840 dom_info.info12 = *info12;
1842 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1843 domain_handle,
1845 &dom_info);
1847 NT_STATUS_NOT_OK_RETURN(status);
1850 return NT_STATUS_OK;
1853 /****************************************************************
1854 ****************************************************************/
1856 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1857 struct rpc_pipe_client *pipe_cli,
1858 struct policy_handle *domain_handle,
1859 struct USER_MODALS_INFO_0 *info0)
1861 NTSTATUS status;
1862 struct samr_DomInfo1 dom_info_1;
1863 struct samr_DomInfo3 dom_info_3;
1865 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1866 pipe_cli,
1867 domain_handle,
1868 &dom_info_1,
1869 &dom_info_3,
1870 NULL,
1871 NULL,
1872 NULL,
1873 NULL);
1874 NT_STATUS_NOT_OK_RETURN(status);
1876 dom_info_1.min_password_length =
1877 info0->usrmod0_min_passwd_len;
1878 dom_info_1.password_history_length =
1879 info0->usrmod0_password_hist_len;
1881 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1882 info0->usrmod0_max_passwd_age);
1883 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
1884 info0->usrmod0_min_passwd_age);
1886 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
1887 info0->usrmod0_force_logoff);
1889 return set_USER_MODALS_INFO_rpc(mem_ctx,
1890 pipe_cli,
1891 domain_handle,
1892 &dom_info_1,
1893 &dom_info_3,
1894 NULL);
1897 /****************************************************************
1898 ****************************************************************/
1900 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
1901 struct rpc_pipe_client *pipe_cli,
1902 struct policy_handle *domain_handle,
1903 struct USER_MODALS_INFO_3 *info3)
1905 NTSTATUS status;
1906 struct samr_DomInfo12 dom_info_12;
1908 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1909 pipe_cli,
1910 domain_handle,
1911 NULL,
1912 NULL,
1913 NULL,
1914 NULL,
1915 NULL,
1916 &dom_info_12);
1917 NT_STATUS_NOT_OK_RETURN(status);
1919 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
1920 info3->usrmod3_lockout_duration);
1921 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
1922 info3->usrmod3_lockout_observation_window);
1923 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
1925 return set_USER_MODALS_INFO_rpc(mem_ctx,
1926 pipe_cli,
1927 domain_handle,
1928 NULL,
1929 NULL,
1930 &dom_info_12);
1933 /****************************************************************
1934 ****************************************************************/
1936 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
1937 struct rpc_pipe_client *pipe_cli,
1938 struct policy_handle *domain_handle,
1939 struct USER_MODALS_INFO_1001 *info1001)
1941 NTSTATUS status;
1942 struct samr_DomInfo1 dom_info_1;
1944 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1945 pipe_cli,
1946 domain_handle,
1947 &dom_info_1,
1948 NULL,
1949 NULL,
1950 NULL,
1951 NULL,
1952 NULL);
1953 NT_STATUS_NOT_OK_RETURN(status);
1955 dom_info_1.min_password_length =
1956 info1001->usrmod1001_min_passwd_len;
1958 return set_USER_MODALS_INFO_rpc(mem_ctx,
1959 pipe_cli,
1960 domain_handle,
1961 &dom_info_1,
1962 NULL,
1963 NULL);
1966 /****************************************************************
1967 ****************************************************************/
1969 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
1970 struct rpc_pipe_client *pipe_cli,
1971 struct policy_handle *domain_handle,
1972 struct USER_MODALS_INFO_1002 *info1002)
1974 NTSTATUS status;
1975 struct samr_DomInfo1 dom_info_1;
1977 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1978 pipe_cli,
1979 domain_handle,
1980 &dom_info_1,
1981 NULL,
1982 NULL,
1983 NULL,
1984 NULL,
1985 NULL);
1986 NT_STATUS_NOT_OK_RETURN(status);
1988 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1989 info1002->usrmod1002_max_passwd_age);
1991 return set_USER_MODALS_INFO_rpc(mem_ctx,
1992 pipe_cli,
1993 domain_handle,
1994 &dom_info_1,
1995 NULL,
1996 NULL);
1999 /****************************************************************
2000 ****************************************************************/
2002 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2003 struct rpc_pipe_client *pipe_cli,
2004 struct policy_handle *domain_handle,
2005 struct USER_MODALS_INFO_1003 *info1003)
2007 NTSTATUS status;
2008 struct samr_DomInfo1 dom_info_1;
2010 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2011 pipe_cli,
2012 domain_handle,
2013 &dom_info_1,
2014 NULL,
2015 NULL,
2016 NULL,
2017 NULL,
2018 NULL);
2019 NT_STATUS_NOT_OK_RETURN(status);
2021 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2022 info1003->usrmod1003_min_passwd_age);
2024 return set_USER_MODALS_INFO_rpc(mem_ctx,
2025 pipe_cli,
2026 domain_handle,
2027 &dom_info_1,
2028 NULL,
2029 NULL);
2032 /****************************************************************
2033 ****************************************************************/
2035 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2036 struct rpc_pipe_client *pipe_cli,
2037 struct policy_handle *domain_handle,
2038 struct USER_MODALS_INFO_1004 *info1004)
2040 NTSTATUS status;
2041 struct samr_DomInfo3 dom_info_3;
2043 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2044 pipe_cli,
2045 domain_handle,
2046 NULL,
2047 &dom_info_3,
2048 NULL,
2049 NULL,
2050 NULL,
2051 NULL);
2052 NT_STATUS_NOT_OK_RETURN(status);
2054 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2055 info1004->usrmod1004_force_logoff);
2057 return set_USER_MODALS_INFO_rpc(mem_ctx,
2058 pipe_cli,
2059 domain_handle,
2060 NULL,
2061 &dom_info_3,
2062 NULL);
2065 /****************************************************************
2066 ****************************************************************/
2068 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2069 struct rpc_pipe_client *pipe_cli,
2070 struct policy_handle *domain_handle,
2071 struct USER_MODALS_INFO_1005 *info1005)
2073 NTSTATUS status;
2074 struct samr_DomInfo1 dom_info_1;
2076 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2077 pipe_cli,
2078 domain_handle,
2079 &dom_info_1,
2080 NULL,
2081 NULL,
2082 NULL,
2083 NULL,
2084 NULL);
2085 NT_STATUS_NOT_OK_RETURN(status);
2087 dom_info_1.password_history_length =
2088 info1005->usrmod1005_password_hist_len;
2090 return set_USER_MODALS_INFO_rpc(mem_ctx,
2091 pipe_cli,
2092 domain_handle,
2093 &dom_info_1,
2094 NULL,
2095 NULL);
2098 /****************************************************************
2099 ****************************************************************/
2101 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2102 struct rpc_pipe_client *pipe_cli,
2103 uint32_t level,
2104 struct policy_handle *domain_handle,
2105 struct dom_sid *domain_sid,
2106 uint8_t *buffer)
2108 struct USER_MODALS_INFO_0 *info0;
2109 struct USER_MODALS_INFO_3 *info3;
2110 struct USER_MODALS_INFO_1001 *info1001;
2111 struct USER_MODALS_INFO_1002 *info1002;
2112 struct USER_MODALS_INFO_1003 *info1003;
2113 struct USER_MODALS_INFO_1004 *info1004;
2114 struct USER_MODALS_INFO_1005 *info1005;
2116 if (!buffer) {
2117 return ERROR_INSUFFICIENT_BUFFER;
2120 switch (level) {
2121 case 0:
2122 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2123 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2124 pipe_cli,
2125 domain_handle,
2126 info0);
2127 case 3:
2128 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2129 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2130 pipe_cli,
2131 domain_handle,
2132 info3);
2133 case 1001:
2134 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2135 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2136 pipe_cli,
2137 domain_handle,
2138 info1001);
2139 case 1002:
2140 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2141 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2142 pipe_cli,
2143 domain_handle,
2144 info1002);
2145 case 1003:
2146 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2147 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2148 pipe_cli,
2149 domain_handle,
2150 info1003);
2151 case 1004:
2152 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2153 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2154 pipe_cli,
2155 domain_handle,
2156 info1004);
2157 case 1005:
2158 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2159 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2160 pipe_cli,
2161 domain_handle,
2162 info1005);
2164 default:
2165 break;
2168 return NT_STATUS_OK;
2171 /****************************************************************
2172 ****************************************************************/
2174 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2175 struct NetUserModalsSet *r)
2177 struct cli_state *cli = NULL;
2178 struct rpc_pipe_client *pipe_cli = NULL;
2179 NTSTATUS status;
2180 WERROR werr;
2182 struct policy_handle connect_handle, domain_handle;
2183 struct dom_sid2 *domain_sid = NULL;
2184 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2186 ZERO_STRUCT(connect_handle);
2187 ZERO_STRUCT(domain_handle);
2189 if (!r->in.buffer) {
2190 return WERR_INVALID_PARAM;
2193 switch (r->in.level) {
2194 case 0:
2195 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2196 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2197 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2198 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2199 break;
2200 case 3:
2201 case 1001:
2202 case 1002:
2203 case 1003:
2204 case 1005:
2205 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2206 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2207 break;
2208 case 1004:
2209 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2210 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2211 break;
2212 case 1:
2213 case 2:
2214 case 1006:
2215 case 1007:
2216 werr = WERR_NOT_SUPPORTED;
2217 break;
2218 default:
2219 werr = WERR_UNKNOWN_LEVEL;
2220 goto done;
2223 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2224 &ndr_table_samr.syntax_id,
2225 &cli,
2226 &pipe_cli);
2227 if (!W_ERROR_IS_OK(werr)) {
2228 goto done;
2231 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2232 SAMR_ACCESS_ENUM_DOMAINS |
2233 SAMR_ACCESS_OPEN_DOMAIN,
2234 access_mask,
2235 &connect_handle,
2236 &domain_handle,
2237 &domain_sid);
2238 if (!W_ERROR_IS_OK(werr)) {
2239 goto done;
2242 status = set_USER_MODALS_INFO_buffer(ctx,
2243 pipe_cli,
2244 r->in.level,
2245 &domain_handle,
2246 domain_sid,
2247 r->in.buffer);
2248 if (!NT_STATUS_IS_OK(status)) {
2249 werr = ntstatus_to_werror(status);
2250 goto done;
2253 done:
2254 if (!cli) {
2255 return werr;
2258 if (ctx->disable_policy_handle_cache) {
2259 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2260 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2263 return werr;
2266 /****************************************************************
2267 ****************************************************************/
2269 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2270 struct NetUserModalsSet *r)
2272 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);