netapi: make non-implemented local calls default to remote "localhost" calls.
[Samba/gebeck_regimport.git] / source3 / lib / netapi / user.c
blobc02dfb9dc927eebc1a7fe904b7958d4f79c62dd6
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 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
367 /****************************************************************
368 ****************************************************************/
370 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
371 struct NetUserDel *r)
373 struct cli_state *cli = NULL;
374 struct rpc_pipe_client *pipe_cli = NULL;
375 NTSTATUS status;
376 WERROR werr;
377 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
378 struct lsa_String lsa_account_name;
379 struct samr_Ids user_rids, name_types;
380 struct dom_sid2 *domain_sid = NULL;
381 struct dom_sid2 user_sid;
383 ZERO_STRUCT(connect_handle);
384 ZERO_STRUCT(builtin_handle);
385 ZERO_STRUCT(domain_handle);
386 ZERO_STRUCT(user_handle);
388 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
389 if (!W_ERROR_IS_OK(werr)) {
390 goto done;
393 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
394 &pipe_cli);
395 if (!W_ERROR_IS_OK(werr)) {
396 goto done;
399 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
400 SAMR_ACCESS_ENUM_DOMAINS |
401 SAMR_ACCESS_OPEN_DOMAIN,
402 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
403 &connect_handle,
404 &domain_handle,
405 &domain_sid);
406 if (!W_ERROR_IS_OK(werr)) {
407 goto done;
410 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
411 &connect_handle,
412 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
413 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
414 &builtin_handle);
415 if (!NT_STATUS_IS_OK(status)) {
416 werr = ntstatus_to_werror(status);
417 goto done;
420 init_lsa_String(&lsa_account_name, r->in.user_name);
422 status = rpccli_samr_LookupNames(pipe_cli, ctx,
423 &domain_handle,
425 &lsa_account_name,
426 &user_rids,
427 &name_types);
428 if (!NT_STATUS_IS_OK(status)) {
429 werr = ntstatus_to_werror(status);
430 goto done;
433 status = rpccli_samr_OpenUser(pipe_cli, ctx,
434 &domain_handle,
435 STD_RIGHT_DELETE_ACCESS,
436 user_rids.ids[0],
437 &user_handle);
438 if (!NT_STATUS_IS_OK(status)) {
439 werr = ntstatus_to_werror(status);
440 goto done;
443 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
445 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
446 &builtin_handle,
447 &user_sid);
448 if (!NT_STATUS_IS_OK(status)) {
449 werr = ntstatus_to_werror(status);
450 goto done;
453 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
454 &user_handle);
455 if (!NT_STATUS_IS_OK(status)) {
456 werr = ntstatus_to_werror(status);
457 goto done;
460 werr = WERR_OK;
462 done:
463 if (!cli) {
464 return werr;
467 if (is_valid_policy_hnd(&user_handle)) {
468 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
471 if (ctx->disable_policy_handle_cache) {
472 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
473 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
474 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
477 return werr;
480 /****************************************************************
481 ****************************************************************/
483 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
484 struct NetUserDel *r)
486 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
489 /****************************************************************
490 ****************************************************************/
492 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
493 struct rpc_pipe_client *pipe_cli,
494 struct policy_handle *domain_handle,
495 struct policy_handle *builtin_handle,
496 const char *user_name,
497 uint32_t rid,
498 uint32_t level,
499 struct samr_UserInfo21 **info21,
500 struct sec_desc_buf **sec_desc)
502 NTSTATUS status;
504 struct policy_handle user_handle;
505 union samr_UserInfo *user_info = NULL;
506 struct samr_RidWithAttributeArray *rid_array = NULL;
507 uint32_t access_mask = SEC_STD_READ_CONTROL |
508 SAMR_USER_ACCESS_GET_ATTRIBUTES |
509 SAMR_USER_ACCESS_GET_NAME_ETC;
511 ZERO_STRUCT(user_handle);
513 switch (level) {
514 case 0:
515 case 1:
516 case 2:
517 case 3:
518 case 10:
519 case 11:
520 case 20:
521 case 23:
522 break;
523 default:
524 return NT_STATUS_INVALID_LEVEL;
527 if (level == 0) {
528 return NT_STATUS_OK;
531 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
532 domain_handle,
533 access_mask,
534 rid,
535 &user_handle);
536 if (!NT_STATUS_IS_OK(status)) {
537 goto done;
540 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
541 &user_handle,
543 &user_info);
544 if (!NT_STATUS_IS_OK(status)) {
545 goto done;
548 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
549 &user_handle,
550 SECINFO_DACL,
551 sec_desc);
552 if (!NT_STATUS_IS_OK(status)) {
553 goto done;
556 if (level == 1) {
557 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
558 &user_handle,
559 &rid_array);
560 if (!NT_STATUS_IS_OK(status)) {
561 goto done;
564 #if 0
565 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
566 &builtin_handle,
567 &sids,
568 &rids);
569 if (!NT_STATUS_IS_OK(status)) {
570 goto done;
572 #endif
575 *info21 = &user_info->info21;
577 done:
578 if (is_valid_policy_hnd(&user_handle)) {
579 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
582 return status;
585 /****************************************************************
586 ****************************************************************/
588 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
589 struct rpc_pipe_client *pipe_cli,
590 struct dom_sid *domain_sid,
591 struct policy_handle *domain_handle,
592 struct policy_handle *builtin_handle,
593 const char *user_name,
594 uint32_t rid,
595 uint32_t level,
596 uint8_t **buffer,
597 uint32_t *num_entries)
599 NTSTATUS status;
601 struct samr_UserInfo21 *info21 = NULL;
602 struct sec_desc_buf *sec_desc = NULL;
603 struct dom_sid sid;
605 struct USER_INFO_0 info0;
606 struct USER_INFO_10 info10;
607 struct USER_INFO_20 info20;
608 struct USER_INFO_23 info23;
610 switch (level) {
611 case 0:
612 case 1:
613 case 2:
614 case 3:
615 case 10:
616 case 11:
617 case 20:
618 case 23:
619 break;
620 default:
621 return NT_STATUS_INVALID_LEVEL;
624 if (level == 0) {
625 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
626 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
628 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
629 (struct USER_INFO_0 **)buffer, num_entries);
631 return NT_STATUS_OK;
634 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
635 domain_handle,
636 builtin_handle,
637 user_name,
638 rid,
639 level,
640 &info21,
641 &sec_desc);
643 if (!NT_STATUS_IS_OK(status)) {
644 goto done;
647 switch (level) {
648 case 10:
649 info10.usri10_name = talloc_strdup(mem_ctx, user_name);
650 NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
652 info10.usri10_comment = talloc_strdup(mem_ctx,
653 info21->description.string);
655 info10.usri10_full_name = talloc_strdup(mem_ctx,
656 info21->full_name.string);
658 info10.usri10_usr_comment = talloc_strdup(mem_ctx,
659 info21->comment.string);
661 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
662 (struct USER_INFO_10 **)buffer, num_entries);
664 break;
666 case 20:
667 info20.usri20_name = talloc_strdup(mem_ctx, user_name);
668 NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
670 info20.usri20_comment = talloc_strdup(mem_ctx,
671 info21->description.string);
673 info20.usri20_full_name = talloc_strdup(mem_ctx,
674 info21->full_name.string);
676 info20.usri20_flags = info21->acct_flags;
677 info20.usri20_user_id = rid;
679 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
680 (struct USER_INFO_20 **)buffer, num_entries);
682 break;
683 case 23:
684 info23.usri23_name = talloc_strdup(mem_ctx, user_name);
685 NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
687 info23.usri23_comment = talloc_strdup(mem_ctx,
688 info21->description.string);
690 info23.usri23_full_name = talloc_strdup(mem_ctx,
691 info21->full_name.string);
693 info23.usri23_flags = info21->acct_flags;
695 if (!sid_compose(&sid, domain_sid, rid)) {
696 return NT_STATUS_NO_MEMORY;
699 info23.usri23_user_sid =
700 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
702 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
703 (struct USER_INFO_23 **)buffer, num_entries);
704 break;
707 done:
708 return status;
711 /****************************************************************
712 ****************************************************************/
714 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
715 struct NetUserEnum *r)
717 struct cli_state *cli = NULL;
718 struct rpc_pipe_client *pipe_cli = NULL;
719 struct policy_handle connect_handle;
720 struct dom_sid2 *domain_sid = NULL;
721 struct policy_handle domain_handle;
722 struct samr_SamArray *sam = NULL;
723 uint32_t filter = ACB_NORMAL;
724 int i;
725 uint32_t entries_read = 0;
727 NTSTATUS status = NT_STATUS_OK;
728 WERROR werr;
730 ZERO_STRUCT(connect_handle);
731 ZERO_STRUCT(domain_handle);
733 if (!r->out.buffer) {
734 return WERR_INVALID_PARAM;
737 *r->out.buffer = NULL;
738 *r->out.entries_read = 0;
740 switch (r->in.level) {
741 case 0:
742 case 10:
743 case 20:
744 case 23:
745 break;
746 case 1:
747 case 2:
748 case 3:
749 case 11:
750 default:
751 return WERR_NOT_SUPPORTED;
754 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
755 if (!W_ERROR_IS_OK(werr)) {
756 goto done;
759 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
760 &pipe_cli);
761 if (!W_ERROR_IS_OK(werr)) {
762 goto done;
765 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
766 SAMR_ACCESS_ENUM_DOMAINS |
767 SAMR_ACCESS_OPEN_DOMAIN,
768 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
769 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
770 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
771 &connect_handle,
772 &domain_handle,
773 &domain_sid);
774 if (!W_ERROR_IS_OK(werr)) {
775 goto done;
778 switch (r->in.filter) {
779 case FILTER_NORMAL_ACCOUNT:
780 filter = ACB_NORMAL;
781 break;
782 case FILTER_TEMP_DUPLICATE_ACCOUNT:
783 filter = ACB_TEMPDUP;
784 break;
785 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
786 filter = ACB_DOMTRUST;
787 break;
788 case FILTER_WORKSTATION_TRUST_ACCOUNT:
789 filter = ACB_WSTRUST;
790 break;
791 case FILTER_SERVER_TRUST_ACCOUNT:
792 filter = ACB_SVRTRUST;
793 break;
794 default:
795 break;
798 status = rpccli_samr_EnumDomainUsers(pipe_cli,
799 ctx,
800 &domain_handle,
801 r->in.resume_handle,
802 filter,
803 &sam,
804 r->in.prefmaxlen,
805 &entries_read);
806 werr = ntstatus_to_werror(status);
807 if (NT_STATUS_IS_ERR(status)) {
808 goto done;
811 for (i=0; i < sam->count; i++) {
813 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
814 domain_sid,
815 &domain_handle,
816 NULL, /*&builtin_handle, */
817 sam->entries[i].name.string,
818 sam->entries[i].idx,
819 r->in.level,
820 r->out.buffer,
821 r->out.entries_read);
822 if (!NT_STATUS_IS_OK(status)) {
823 werr = ntstatus_to_werror(status);
824 goto done;
828 done:
829 if (!cli) {
830 return werr;
833 /* if last query */
834 if (NT_STATUS_IS_OK(status) ||
835 NT_STATUS_IS_ERR(status)) {
837 if (ctx->disable_policy_handle_cache) {
838 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
839 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
843 return werr;
846 /****************************************************************
847 ****************************************************************/
849 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
850 struct NetUserEnum *r)
852 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
855 /****************************************************************
856 ****************************************************************/
858 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
859 struct samr_DispInfoGeneral *info,
860 uint32_t *entries_read,
861 void **buffer)
863 struct NET_DISPLAY_USER *user = NULL;
864 int i;
866 user = TALLOC_ZERO_ARRAY(mem_ctx,
867 struct NET_DISPLAY_USER,
868 info->count);
869 W_ERROR_HAVE_NO_MEMORY(user);
871 for (i = 0; i < info->count; i++) {
872 user[i].usri1_name = talloc_strdup(mem_ctx,
873 info->entries[i].account_name.string);
874 user[i].usri1_comment = talloc_strdup(mem_ctx,
875 info->entries[i].description.string);
876 user[i].usri1_flags =
877 info->entries[i].acct_flags;
878 user[i].usri1_full_name = talloc_strdup(mem_ctx,
879 info->entries[i].full_name.string);
880 user[i].usri1_user_id =
881 info->entries[i].rid;
882 user[i].usri1_next_index =
883 info->entries[i].idx;
885 if (!user[i].usri1_name) {
886 return WERR_NOMEM;
890 *buffer = talloc_memdup(mem_ctx, user,
891 sizeof(struct NET_DISPLAY_USER) * info->count);
892 W_ERROR_HAVE_NO_MEMORY(*buffer);
894 *entries_read = info->count;
896 return WERR_OK;
899 /****************************************************************
900 ****************************************************************/
902 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
903 struct samr_DispInfoFull *info,
904 uint32_t *entries_read,
905 void **buffer)
907 struct NET_DISPLAY_MACHINE *machine = NULL;
908 int i;
910 machine = TALLOC_ZERO_ARRAY(mem_ctx,
911 struct NET_DISPLAY_MACHINE,
912 info->count);
913 W_ERROR_HAVE_NO_MEMORY(machine);
915 for (i = 0; i < info->count; i++) {
916 machine[i].usri2_name = talloc_strdup(mem_ctx,
917 info->entries[i].account_name.string);
918 machine[i].usri2_comment = talloc_strdup(mem_ctx,
919 info->entries[i].description.string);
920 machine[i].usri2_flags =
921 info->entries[i].acct_flags;
922 machine[i].usri2_user_id =
923 info->entries[i].rid;
924 machine[i].usri2_next_index =
925 info->entries[i].idx;
927 if (!machine[i].usri2_name) {
928 return WERR_NOMEM;
932 *buffer = talloc_memdup(mem_ctx, machine,
933 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
934 W_ERROR_HAVE_NO_MEMORY(*buffer);
936 *entries_read = info->count;
938 return WERR_OK;
941 /****************************************************************
942 ****************************************************************/
944 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
945 struct samr_DispInfoFullGroups *info,
946 uint32_t *entries_read,
947 void **buffer)
949 struct NET_DISPLAY_GROUP *group = NULL;
950 int i;
952 group = TALLOC_ZERO_ARRAY(mem_ctx,
953 struct NET_DISPLAY_GROUP,
954 info->count);
955 W_ERROR_HAVE_NO_MEMORY(group);
957 for (i = 0; i < info->count; i++) {
958 group[i].grpi3_name = talloc_strdup(mem_ctx,
959 info->entries[i].account_name.string);
960 group[i].grpi3_comment = talloc_strdup(mem_ctx,
961 info->entries[i].description.string);
962 group[i].grpi3_group_id =
963 info->entries[i].rid;
964 group[i].grpi3_attributes =
965 info->entries[i].acct_flags;
966 group[i].grpi3_next_index =
967 info->entries[i].idx;
969 if (!group[i].grpi3_name) {
970 return WERR_NOMEM;
974 *buffer = talloc_memdup(mem_ctx, group,
975 sizeof(struct NET_DISPLAY_GROUP) * info->count);
976 W_ERROR_HAVE_NO_MEMORY(*buffer);
978 *entries_read = info->count;
980 return WERR_OK;
984 /****************************************************************
985 ****************************************************************/
987 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
988 union samr_DispInfo *info,
989 uint32_t level,
990 uint32_t *entries_read,
991 void **buffer)
993 switch (level) {
994 case 1:
995 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
996 &info->info1,
997 entries_read,
998 buffer);
999 case 2:
1000 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1001 &info->info2,
1002 entries_read,
1003 buffer);
1004 case 3:
1005 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1006 &info->info3,
1007 entries_read,
1008 buffer);
1009 default:
1010 return WERR_UNKNOWN_LEVEL;
1013 return WERR_OK;
1016 /****************************************************************
1017 ****************************************************************/
1019 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1020 struct NetQueryDisplayInformation *r)
1022 struct cli_state *cli = NULL;
1023 struct rpc_pipe_client *pipe_cli = NULL;
1024 struct policy_handle connect_handle;
1025 struct dom_sid2 *domain_sid = NULL;
1026 struct policy_handle domain_handle;
1027 union samr_DispInfo info;
1029 uint32_t total_size = 0;
1030 uint32_t returned_size = 0;
1032 NTSTATUS status = NT_STATUS_OK;
1033 WERROR werr;
1035 ZERO_STRUCT(connect_handle);
1036 ZERO_STRUCT(domain_handle);
1038 switch (r->in.level) {
1039 case 1:
1040 case 2:
1041 case 3:
1042 break;
1043 default:
1044 return WERR_UNKNOWN_LEVEL;
1047 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1048 if (!W_ERROR_IS_OK(werr)) {
1049 goto done;
1052 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1053 &pipe_cli);
1054 if (!W_ERROR_IS_OK(werr)) {
1055 goto done;
1058 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1059 SAMR_ACCESS_ENUM_DOMAINS |
1060 SAMR_ACCESS_OPEN_DOMAIN,
1061 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1062 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1063 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1064 &connect_handle,
1065 &domain_handle,
1066 &domain_sid);
1067 if (!W_ERROR_IS_OK(werr)) {
1068 goto done;
1071 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1072 ctx,
1073 &domain_handle,
1074 r->in.level,
1075 r->in.idx,
1076 r->in.entries_requested,
1077 r->in.prefmaxlen,
1078 &total_size,
1079 &returned_size,
1080 &info);
1081 if (!NT_STATUS_IS_OK(status)) {
1082 werr = ntstatus_to_werror(status);
1083 goto done;
1086 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1087 r->in.level,
1088 r->out.entries_read,
1089 r->out.buffer);
1090 done:
1091 if (!cli) {
1092 return werr;
1095 /* if last query */
1096 if (NT_STATUS_IS_OK(status) ||
1097 NT_STATUS_IS_ERR(status)) {
1099 if (ctx->disable_policy_handle_cache) {
1100 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1101 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1105 return werr;
1109 /****************************************************************
1110 ****************************************************************/
1113 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1114 struct NetQueryDisplayInformation *r)
1116 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1119 /****************************************************************
1120 ****************************************************************/
1122 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1123 struct NetUserChangePassword *r)
1125 return WERR_NOT_SUPPORTED;
1128 /****************************************************************
1129 ****************************************************************/
1131 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1132 struct NetUserChangePassword *r)
1134 return WERR_NOT_SUPPORTED;
1137 /****************************************************************
1138 ****************************************************************/
1140 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1141 struct NetUserGetInfo *r)
1143 struct cli_state *cli = NULL;
1144 struct rpc_pipe_client *pipe_cli = NULL;
1145 NTSTATUS status;
1146 WERROR werr;
1148 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1149 struct lsa_String lsa_account_name;
1150 struct dom_sid2 *domain_sid = NULL;
1151 struct samr_Ids user_rids, name_types;
1152 uint32_t num_entries = 0;
1154 ZERO_STRUCT(connect_handle);
1155 ZERO_STRUCT(domain_handle);
1156 ZERO_STRUCT(builtin_handle);
1157 ZERO_STRUCT(user_handle);
1159 if (!r->out.buffer) {
1160 return WERR_INVALID_PARAM;
1163 switch (r->in.level) {
1164 case 0:
1165 /* case 1: */
1166 case 10:
1167 case 20:
1168 case 23:
1169 break;
1170 default:
1171 werr = WERR_NOT_SUPPORTED;
1172 goto done;
1175 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1176 if (!W_ERROR_IS_OK(werr)) {
1177 goto done;
1180 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1181 &pipe_cli);
1182 if (!W_ERROR_IS_OK(werr)) {
1183 goto done;
1186 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1187 SAMR_ACCESS_ENUM_DOMAINS |
1188 SAMR_ACCESS_OPEN_DOMAIN,
1189 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1190 &connect_handle,
1191 &domain_handle,
1192 &domain_sid);
1193 if (!W_ERROR_IS_OK(werr)) {
1194 goto done;
1197 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1198 SAMR_ACCESS_ENUM_DOMAINS |
1199 SAMR_ACCESS_OPEN_DOMAIN,
1200 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1201 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1202 &connect_handle,
1203 &builtin_handle);
1204 if (!W_ERROR_IS_OK(werr)) {
1205 goto done;
1208 init_lsa_String(&lsa_account_name, r->in.user_name);
1210 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1211 &domain_handle,
1213 &lsa_account_name,
1214 &user_rids,
1215 &name_types);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 werr = ntstatus_to_werror(status);
1218 goto done;
1221 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1222 domain_sid,
1223 &domain_handle,
1224 &builtin_handle,
1225 r->in.user_name,
1226 user_rids.ids[0],
1227 r->in.level,
1228 r->out.buffer,
1229 &num_entries);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 werr = ntstatus_to_werror(status);
1232 goto done;
1235 done:
1236 if (!cli) {
1237 return werr;
1240 if (is_valid_policy_hnd(&user_handle)) {
1241 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1244 if (ctx->disable_policy_handle_cache) {
1245 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1246 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1249 return werr;
1252 /****************************************************************
1253 ****************************************************************/
1255 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1256 struct NetUserGetInfo *r)
1258 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1261 /****************************************************************
1262 ****************************************************************/
1264 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1265 struct NetUserSetInfo *r)
1267 struct cli_state *cli = NULL;
1268 struct rpc_pipe_client *pipe_cli = NULL;
1269 NTSTATUS status;
1270 WERROR werr;
1272 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1273 struct lsa_String lsa_account_name;
1274 struct dom_sid2 *domain_sid = NULL;
1275 struct samr_Ids user_rids, name_types;
1276 union samr_UserInfo user_info;
1278 struct USER_INFO_X uX;
1280 ZERO_STRUCT(connect_handle);
1281 ZERO_STRUCT(domain_handle);
1282 ZERO_STRUCT(builtin_handle);
1283 ZERO_STRUCT(user_handle);
1285 if (!r->in.buffer) {
1286 return WERR_INVALID_PARAM;
1289 switch (r->in.level) {
1290 case 0:
1291 case 1007:
1292 break;
1293 default:
1294 werr = WERR_NOT_SUPPORTED;
1295 goto done;
1298 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1299 if (!W_ERROR_IS_OK(werr)) {
1300 goto done;
1303 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1304 &pipe_cli);
1305 if (!W_ERROR_IS_OK(werr)) {
1306 goto done;
1309 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1310 SAMR_ACCESS_ENUM_DOMAINS |
1311 SAMR_ACCESS_OPEN_DOMAIN,
1312 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1313 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1314 &connect_handle,
1315 &domain_handle,
1316 &domain_sid);
1317 if (!W_ERROR_IS_OK(werr)) {
1318 goto done;
1321 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1322 SAMR_ACCESS_ENUM_DOMAINS |
1323 SAMR_ACCESS_OPEN_DOMAIN,
1324 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1325 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1326 &connect_handle,
1327 &builtin_handle);
1328 if (!W_ERROR_IS_OK(werr)) {
1329 goto done;
1332 init_lsa_String(&lsa_account_name, r->in.user_name);
1334 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1335 &domain_handle,
1337 &lsa_account_name,
1338 &user_rids,
1339 &name_types);
1340 if (!NT_STATUS_IS_OK(status)) {
1341 werr = ntstatus_to_werror(status);
1342 goto done;
1345 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1346 &domain_handle,
1347 SAMR_USER_ACCESS_SET_ATTRIBUTES,
1348 user_rids.ids[0],
1349 &user_handle);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 werr = ntstatus_to_werror(status);
1352 goto done;
1355 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 werr = ntstatus_to_werror(status);
1358 goto done;
1361 convert_USER_INFO_X_to_samr_user_info21(&uX, &user_info.info21);
1363 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
1364 &user_handle,
1366 &user_info);
1367 if (!NT_STATUS_IS_OK(status)) {
1368 werr = ntstatus_to_werror(status);
1369 goto done;
1372 werr = WERR_OK;
1374 done:
1375 if (!cli) {
1376 return werr;
1379 if (is_valid_policy_hnd(&user_handle)) {
1380 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1383 if (ctx->disable_policy_handle_cache) {
1384 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1385 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1386 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1389 return werr;
1392 /****************************************************************
1393 ****************************************************************/
1395 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1396 struct NetUserSetInfo *r)
1398 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1401 /****************************************************************
1402 ****************************************************************/
1404 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1405 struct rpc_pipe_client *pipe_cli,
1406 struct policy_handle *domain_handle,
1407 struct samr_DomInfo1 *info1,
1408 struct samr_DomInfo3 *info3,
1409 struct samr_DomInfo5 *info5,
1410 struct samr_DomInfo6 *info6,
1411 struct samr_DomInfo7 *info7,
1412 struct samr_DomInfo12 *info12)
1414 NTSTATUS status;
1415 union samr_DomainInfo *dom_info = NULL;
1417 if (info1) {
1418 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1419 domain_handle,
1421 &dom_info);
1422 NT_STATUS_NOT_OK_RETURN(status);
1424 *info1 = dom_info->info1;
1427 if (info3) {
1428 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1429 domain_handle,
1431 &dom_info);
1432 NT_STATUS_NOT_OK_RETURN(status);
1434 *info3 = dom_info->info3;
1437 if (info5) {
1438 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1439 domain_handle,
1441 &dom_info);
1442 NT_STATUS_NOT_OK_RETURN(status);
1444 *info5 = dom_info->info5;
1447 if (info6) {
1448 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1449 domain_handle,
1451 &dom_info);
1452 NT_STATUS_NOT_OK_RETURN(status);
1454 *info6 = dom_info->info6;
1457 if (info7) {
1458 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1459 domain_handle,
1461 &dom_info);
1462 NT_STATUS_NOT_OK_RETURN(status);
1464 *info7 = dom_info->info7;
1467 if (info12) {
1468 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1469 domain_handle,
1471 &dom_info);
1472 NT_STATUS_NOT_OK_RETURN(status);
1474 *info12 = dom_info->info12;
1477 return NT_STATUS_OK;
1480 /****************************************************************
1481 ****************************************************************/
1483 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1484 struct rpc_pipe_client *pipe_cli,
1485 struct policy_handle *domain_handle,
1486 struct USER_MODALS_INFO_0 *info0)
1488 NTSTATUS status;
1489 struct samr_DomInfo1 dom_info1;
1490 struct samr_DomInfo3 dom_info3;
1492 ZERO_STRUCTP(info0);
1494 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1495 pipe_cli,
1496 domain_handle,
1497 &dom_info1,
1498 &dom_info3,
1499 NULL,
1500 NULL,
1501 NULL,
1502 NULL);
1503 NT_STATUS_NOT_OK_RETURN(status);
1505 info0->usrmod0_min_passwd_len =
1506 dom_info1.min_password_length;
1507 info0->usrmod0_max_passwd_age =
1508 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1509 info0->usrmod0_min_passwd_age =
1510 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
1511 info0->usrmod0_password_hist_len =
1512 dom_info1.password_history_length;
1514 info0->usrmod0_force_logoff =
1515 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
1517 return NT_STATUS_OK;
1520 /****************************************************************
1521 ****************************************************************/
1523 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
1524 struct rpc_pipe_client *pipe_cli,
1525 struct policy_handle *domain_handle,
1526 struct USER_MODALS_INFO_1 *info1)
1528 NTSTATUS status;
1529 struct samr_DomInfo6 dom_info6;
1530 struct samr_DomInfo7 dom_info7;
1532 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1533 pipe_cli,
1534 domain_handle,
1535 NULL,
1536 NULL,
1537 NULL,
1538 &dom_info6,
1539 &dom_info7,
1540 NULL);
1541 NT_STATUS_NOT_OK_RETURN(status);
1543 info1->usrmod1_primary =
1544 talloc_strdup(mem_ctx, dom_info6.primary.string);
1546 info1->usrmod1_role = dom_info7.role;
1548 return NT_STATUS_OK;
1551 /****************************************************************
1552 ****************************************************************/
1554 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
1555 struct rpc_pipe_client *pipe_cli,
1556 struct policy_handle *domain_handle,
1557 struct dom_sid *domain_sid,
1558 struct USER_MODALS_INFO_2 *info2)
1560 NTSTATUS status;
1561 struct samr_DomInfo5 dom_info5;
1563 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1564 pipe_cli,
1565 domain_handle,
1566 NULL,
1567 NULL,
1568 &dom_info5,
1569 NULL,
1570 NULL,
1571 NULL);
1572 NT_STATUS_NOT_OK_RETURN(status);
1574 info2->usrmod2_domain_name =
1575 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
1576 info2->usrmod2_domain_id =
1577 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
1579 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
1580 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
1582 return NT_STATUS_OK;
1585 /****************************************************************
1586 ****************************************************************/
1588 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
1589 struct rpc_pipe_client *pipe_cli,
1590 struct policy_handle *domain_handle,
1591 struct USER_MODALS_INFO_3 *info3)
1593 NTSTATUS status;
1594 struct samr_DomInfo12 dom_info12;
1596 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1597 pipe_cli,
1598 domain_handle,
1599 NULL,
1600 NULL,
1601 NULL,
1602 NULL,
1603 NULL,
1604 &dom_info12);
1605 NT_STATUS_NOT_OK_RETURN(status);
1607 info3->usrmod3_lockout_duration =
1608 nt_time_to_unix_abs(&dom_info12.lockout_duration);
1609 info3->usrmod3_lockout_observation_window =
1610 nt_time_to_unix_abs(&dom_info12.lockout_window);
1611 info3->usrmod3_lockout_threshold =
1612 dom_info12.lockout_threshold;
1614 return NT_STATUS_OK;
1617 /****************************************************************
1618 ****************************************************************/
1620 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
1621 struct rpc_pipe_client *pipe_cli,
1622 uint32_t level,
1623 struct policy_handle *domain_handle,
1624 struct dom_sid *domain_sid,
1625 uint8_t **buffer)
1627 NTSTATUS status;
1629 struct USER_MODALS_INFO_0 info0;
1630 struct USER_MODALS_INFO_1 info1;
1631 struct USER_MODALS_INFO_2 info2;
1632 struct USER_MODALS_INFO_3 info3;
1634 if (!buffer) {
1635 return ERROR_INSUFFICIENT_BUFFER;
1638 switch (level) {
1639 case 0:
1640 status = query_USER_MODALS_INFO_0(mem_ctx,
1641 pipe_cli,
1642 domain_handle,
1643 &info0);
1644 NT_STATUS_NOT_OK_RETURN(status);
1646 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
1647 sizeof(info0));
1648 break;
1650 case 1:
1651 status = query_USER_MODALS_INFO_1(mem_ctx,
1652 pipe_cli,
1653 domain_handle,
1654 &info1);
1655 NT_STATUS_NOT_OK_RETURN(status);
1657 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
1658 sizeof(info1));
1659 break;
1660 case 2:
1661 status = query_USER_MODALS_INFO_2(mem_ctx,
1662 pipe_cli,
1663 domain_handle,
1664 domain_sid,
1665 &info2);
1666 NT_STATUS_NOT_OK_RETURN(status);
1668 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
1669 sizeof(info2));
1670 break;
1671 case 3:
1672 status = query_USER_MODALS_INFO_3(mem_ctx,
1673 pipe_cli,
1674 domain_handle,
1675 &info3);
1676 NT_STATUS_NOT_OK_RETURN(status);
1678 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
1679 sizeof(info3));
1680 break;
1681 default:
1682 break;
1685 NT_STATUS_HAVE_NO_MEMORY(*buffer);
1687 return NT_STATUS_OK;
1690 /****************************************************************
1691 ****************************************************************/
1693 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
1694 struct NetUserModalsGet *r)
1696 struct cli_state *cli = NULL;
1697 struct rpc_pipe_client *pipe_cli = NULL;
1698 NTSTATUS status;
1699 WERROR werr;
1701 struct policy_handle connect_handle, domain_handle;
1702 struct dom_sid2 *domain_sid = NULL;
1703 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
1705 ZERO_STRUCT(connect_handle);
1706 ZERO_STRUCT(domain_handle);
1708 if (!r->out.buffer) {
1709 return WERR_INVALID_PARAM;
1712 switch (r->in.level) {
1713 case 0:
1714 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1715 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1716 break;
1717 case 1:
1718 case 2:
1719 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1720 break;
1721 case 3:
1722 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
1723 break;
1724 default:
1725 werr = WERR_UNKNOWN_LEVEL;
1726 goto done;
1729 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1730 if (!W_ERROR_IS_OK(werr)) {
1731 goto done;
1734 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1735 &pipe_cli);
1736 if (!W_ERROR_IS_OK(werr)) {
1737 goto done;
1740 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1741 SAMR_ACCESS_ENUM_DOMAINS |
1742 SAMR_ACCESS_OPEN_DOMAIN,
1743 access_mask,
1744 &connect_handle,
1745 &domain_handle,
1746 &domain_sid);
1747 if (!W_ERROR_IS_OK(werr)) {
1748 goto done;
1751 /* 0: 1 + 3 */
1752 /* 1: 6 + 7 */
1753 /* 2: 5 */
1754 /* 3: 12 (DomainInfo2) */
1756 status = query_USER_MODALS_INFO_to_buffer(ctx,
1757 pipe_cli,
1758 r->in.level,
1759 &domain_handle,
1760 domain_sid,
1761 r->out.buffer);
1762 if (!NT_STATUS_IS_OK(status)) {
1763 werr = ntstatus_to_werror(status);
1764 goto done;
1767 done:
1768 if (!cli) {
1769 return werr;
1772 if (ctx->disable_policy_handle_cache) {
1773 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1774 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1777 return werr;
1780 /****************************************************************
1781 ****************************************************************/
1783 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
1784 struct NetUserModalsGet *r)
1786 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
1789 /****************************************************************
1790 ****************************************************************/
1792 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1793 struct rpc_pipe_client *pipe_cli,
1794 struct policy_handle *domain_handle,
1795 struct samr_DomInfo1 *info1,
1796 struct samr_DomInfo3 *info3,
1797 struct samr_DomInfo12 *info12)
1799 NTSTATUS status;
1800 union samr_DomainInfo dom_info;
1802 if (info1) {
1804 ZERO_STRUCT(dom_info);
1806 dom_info.info1 = *info1;
1808 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1809 domain_handle,
1811 &dom_info);
1812 NT_STATUS_NOT_OK_RETURN(status);
1815 if (info3) {
1817 ZERO_STRUCT(dom_info);
1819 dom_info.info3 = *info3;
1821 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1822 domain_handle,
1824 &dom_info);
1826 NT_STATUS_NOT_OK_RETURN(status);
1829 if (info12) {
1831 ZERO_STRUCT(dom_info);
1833 dom_info.info12 = *info12;
1835 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1836 domain_handle,
1838 &dom_info);
1840 NT_STATUS_NOT_OK_RETURN(status);
1843 return NT_STATUS_OK;
1846 /****************************************************************
1847 ****************************************************************/
1849 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1850 struct rpc_pipe_client *pipe_cli,
1851 struct policy_handle *domain_handle,
1852 struct USER_MODALS_INFO_0 *info0)
1854 NTSTATUS status;
1855 struct samr_DomInfo1 dom_info_1;
1856 struct samr_DomInfo3 dom_info_3;
1858 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1859 pipe_cli,
1860 domain_handle,
1861 &dom_info_1,
1862 &dom_info_3,
1863 NULL,
1864 NULL,
1865 NULL,
1866 NULL);
1867 NT_STATUS_NOT_OK_RETURN(status);
1869 dom_info_1.min_password_length =
1870 info0->usrmod0_min_passwd_len;
1871 dom_info_1.password_history_length =
1872 info0->usrmod0_password_hist_len;
1874 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1875 info0->usrmod0_max_passwd_age);
1876 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
1877 info0->usrmod0_min_passwd_age);
1879 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
1880 info0->usrmod0_force_logoff);
1882 return set_USER_MODALS_INFO_rpc(mem_ctx,
1883 pipe_cli,
1884 domain_handle,
1885 &dom_info_1,
1886 &dom_info_3,
1887 NULL);
1890 /****************************************************************
1891 ****************************************************************/
1893 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
1894 struct rpc_pipe_client *pipe_cli,
1895 struct policy_handle *domain_handle,
1896 struct USER_MODALS_INFO_3 *info3)
1898 NTSTATUS status;
1899 struct samr_DomInfo12 dom_info_12;
1901 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1902 pipe_cli,
1903 domain_handle,
1904 NULL,
1905 NULL,
1906 NULL,
1907 NULL,
1908 NULL,
1909 &dom_info_12);
1910 NT_STATUS_NOT_OK_RETURN(status);
1912 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
1913 info3->usrmod3_lockout_duration);
1914 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
1915 info3->usrmod3_lockout_observation_window);
1916 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
1918 return set_USER_MODALS_INFO_rpc(mem_ctx,
1919 pipe_cli,
1920 domain_handle,
1921 NULL,
1922 NULL,
1923 &dom_info_12);
1926 /****************************************************************
1927 ****************************************************************/
1929 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
1930 struct rpc_pipe_client *pipe_cli,
1931 struct policy_handle *domain_handle,
1932 struct USER_MODALS_INFO_1001 *info1001)
1934 NTSTATUS status;
1935 struct samr_DomInfo1 dom_info_1;
1937 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1938 pipe_cli,
1939 domain_handle,
1940 &dom_info_1,
1941 NULL,
1942 NULL,
1943 NULL,
1944 NULL,
1945 NULL);
1946 NT_STATUS_NOT_OK_RETURN(status);
1948 dom_info_1.min_password_length =
1949 info1001->usrmod1001_min_passwd_len;
1951 return set_USER_MODALS_INFO_rpc(mem_ctx,
1952 pipe_cli,
1953 domain_handle,
1954 &dom_info_1,
1955 NULL,
1956 NULL);
1959 /****************************************************************
1960 ****************************************************************/
1962 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
1963 struct rpc_pipe_client *pipe_cli,
1964 struct policy_handle *domain_handle,
1965 struct USER_MODALS_INFO_1002 *info1002)
1967 NTSTATUS status;
1968 struct samr_DomInfo1 dom_info_1;
1970 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1971 pipe_cli,
1972 domain_handle,
1973 &dom_info_1,
1974 NULL,
1975 NULL,
1976 NULL,
1977 NULL,
1978 NULL);
1979 NT_STATUS_NOT_OK_RETURN(status);
1981 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1982 info1002->usrmod1002_max_passwd_age);
1984 return set_USER_MODALS_INFO_rpc(mem_ctx,
1985 pipe_cli,
1986 domain_handle,
1987 &dom_info_1,
1988 NULL,
1989 NULL);
1992 /****************************************************************
1993 ****************************************************************/
1995 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
1996 struct rpc_pipe_client *pipe_cli,
1997 struct policy_handle *domain_handle,
1998 struct USER_MODALS_INFO_1003 *info1003)
2000 NTSTATUS status;
2001 struct samr_DomInfo1 dom_info_1;
2003 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2004 pipe_cli,
2005 domain_handle,
2006 &dom_info_1,
2007 NULL,
2008 NULL,
2009 NULL,
2010 NULL,
2011 NULL);
2012 NT_STATUS_NOT_OK_RETURN(status);
2014 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2015 info1003->usrmod1003_min_passwd_age);
2017 return set_USER_MODALS_INFO_rpc(mem_ctx,
2018 pipe_cli,
2019 domain_handle,
2020 &dom_info_1,
2021 NULL,
2022 NULL);
2025 /****************************************************************
2026 ****************************************************************/
2028 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2029 struct rpc_pipe_client *pipe_cli,
2030 struct policy_handle *domain_handle,
2031 struct USER_MODALS_INFO_1004 *info1004)
2033 NTSTATUS status;
2034 struct samr_DomInfo3 dom_info_3;
2036 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2037 pipe_cli,
2038 domain_handle,
2039 NULL,
2040 &dom_info_3,
2041 NULL,
2042 NULL,
2043 NULL,
2044 NULL);
2045 NT_STATUS_NOT_OK_RETURN(status);
2047 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2048 info1004->usrmod1004_force_logoff);
2050 return set_USER_MODALS_INFO_rpc(mem_ctx,
2051 pipe_cli,
2052 domain_handle,
2053 NULL,
2054 &dom_info_3,
2055 NULL);
2058 /****************************************************************
2059 ****************************************************************/
2061 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2062 struct rpc_pipe_client *pipe_cli,
2063 struct policy_handle *domain_handle,
2064 struct USER_MODALS_INFO_1005 *info1005)
2066 NTSTATUS status;
2067 struct samr_DomInfo1 dom_info_1;
2069 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2070 pipe_cli,
2071 domain_handle,
2072 &dom_info_1,
2073 NULL,
2074 NULL,
2075 NULL,
2076 NULL,
2077 NULL);
2078 NT_STATUS_NOT_OK_RETURN(status);
2080 dom_info_1.password_history_length =
2081 info1005->usrmod1005_password_hist_len;
2083 return set_USER_MODALS_INFO_rpc(mem_ctx,
2084 pipe_cli,
2085 domain_handle,
2086 &dom_info_1,
2087 NULL,
2088 NULL);
2091 /****************************************************************
2092 ****************************************************************/
2094 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2095 struct rpc_pipe_client *pipe_cli,
2096 uint32_t level,
2097 struct policy_handle *domain_handle,
2098 struct dom_sid *domain_sid,
2099 uint8_t *buffer)
2101 struct USER_MODALS_INFO_0 *info0;
2102 struct USER_MODALS_INFO_3 *info3;
2103 struct USER_MODALS_INFO_1001 *info1001;
2104 struct USER_MODALS_INFO_1002 *info1002;
2105 struct USER_MODALS_INFO_1003 *info1003;
2106 struct USER_MODALS_INFO_1004 *info1004;
2107 struct USER_MODALS_INFO_1005 *info1005;
2109 if (!buffer) {
2110 return ERROR_INSUFFICIENT_BUFFER;
2113 switch (level) {
2114 case 0:
2115 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2116 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2117 pipe_cli,
2118 domain_handle,
2119 info0);
2120 case 3:
2121 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2122 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2123 pipe_cli,
2124 domain_handle,
2125 info3);
2126 case 1001:
2127 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2128 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2129 pipe_cli,
2130 domain_handle,
2131 info1001);
2132 case 1002:
2133 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2134 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2135 pipe_cli,
2136 domain_handle,
2137 info1002);
2138 case 1003:
2139 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2140 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2141 pipe_cli,
2142 domain_handle,
2143 info1003);
2144 case 1004:
2145 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2146 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2147 pipe_cli,
2148 domain_handle,
2149 info1004);
2150 case 1005:
2151 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2152 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2153 pipe_cli,
2154 domain_handle,
2155 info1005);
2157 default:
2158 break;
2161 return NT_STATUS_OK;
2164 /****************************************************************
2165 ****************************************************************/
2167 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2168 struct NetUserModalsSet *r)
2170 struct cli_state *cli = NULL;
2171 struct rpc_pipe_client *pipe_cli = NULL;
2172 NTSTATUS status;
2173 WERROR werr;
2175 struct policy_handle connect_handle, domain_handle;
2176 struct dom_sid2 *domain_sid = NULL;
2177 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2179 ZERO_STRUCT(connect_handle);
2180 ZERO_STRUCT(domain_handle);
2182 if (!r->in.buffer) {
2183 return WERR_INVALID_PARAM;
2186 switch (r->in.level) {
2187 case 0:
2188 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2189 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2190 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2191 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2192 break;
2193 case 3:
2194 case 1001:
2195 case 1002:
2196 case 1003:
2197 case 1005:
2198 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2199 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2200 break;
2201 case 1004:
2202 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2203 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2204 break;
2205 case 1:
2206 case 2:
2207 case 1006:
2208 case 1007:
2209 werr = WERR_NOT_SUPPORTED;
2210 break;
2211 default:
2212 werr = WERR_UNKNOWN_LEVEL;
2213 goto done;
2216 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
2217 if (!W_ERROR_IS_OK(werr)) {
2218 goto done;
2221 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
2222 &pipe_cli);
2223 if (!W_ERROR_IS_OK(werr)) {
2224 goto done;
2227 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2228 SAMR_ACCESS_ENUM_DOMAINS |
2229 SAMR_ACCESS_OPEN_DOMAIN,
2230 access_mask,
2231 &connect_handle,
2232 &domain_handle,
2233 &domain_sid);
2234 if (!W_ERROR_IS_OK(werr)) {
2235 goto done;
2238 status = set_USER_MODALS_INFO_buffer(ctx,
2239 pipe_cli,
2240 r->in.level,
2241 &domain_handle,
2242 domain_sid,
2243 r->in.buffer);
2244 if (!NT_STATUS_IS_OK(status)) {
2245 werr = ntstatus_to_werror(status);
2246 goto done;
2249 done:
2250 if (!cli) {
2251 return werr;
2254 if (ctx->disable_policy_handle_cache) {
2255 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2256 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2259 return werr;
2262 /****************************************************************
2263 ****************************************************************/
2265 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2266 struct NetUserModalsSet *r)
2268 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);