2 * Unix SMB/CIFS implementation.
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/>.
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 = 0;
34 struct samr_LogonHours zero_logon_hours;
35 struct lsa_BinaryString zero_parameters;
39 ZERO_STRUCT(zero_logon_hours);
40 ZERO_STRUCT(zero_parameters);
42 if (infoX->usriX_flags) {
43 fields_present |= SAMR_FIELD_ACCT_FLAGS;
45 if (infoX->usriX_name) {
46 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
48 if (infoX->usriX_password) {
49 fields_present |= SAMR_FIELD_PASSWORD;
51 if (infoX->usriX_flags) {
52 fields_present |= SAMR_FIELD_ACCT_FLAGS;
54 if (infoX->usriX_name) {
55 fields_present |= SAMR_FIELD_FULL_NAME;
57 if (infoX->usriX_home_dir) {
58 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
60 if (infoX->usriX_script_path) {
61 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
63 if (infoX->usriX_comment) {
64 fields_present |= SAMR_FIELD_DESCRIPTION;
66 if (infoX->usriX_password_age) {
67 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
69 if (infoX->usriX_full_name) {
70 fields_present |= SAMR_FIELD_FULL_NAME;
72 if (infoX->usriX_usr_comment) {
73 fields_present |= SAMR_FIELD_COMMENT;
75 if (infoX->usriX_profile) {
76 fields_present |= SAMR_FIELD_PROFILE_PATH;
78 if (infoX->usriX_home_dir_drive) {
79 fields_present |= SAMR_FIELD_HOME_DRIVE;
81 if (infoX->usriX_primary_group_id) {
82 fields_present |= SAMR_FIELD_PRIMARY_GID;
84 if (infoX->usriX_country_code) {
85 fields_present |= SAMR_FIELD_COUNTRY_CODE;
87 if (infoX->usriX_workstations) {
88 fields_present |= SAMR_FIELD_WORKSTATIONS;
91 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
93 /* TODO: infoX->usriX_priv */
94 init_samr_user_info21(info21,
102 infoX->usriX_full_name,
103 infoX->usriX_home_dir,
104 infoX->usriX_home_dir_drive,
105 infoX->usriX_script_path,
106 infoX->usriX_profile,
107 infoX->usriX_comment,
108 infoX->usriX_workstations,
109 infoX->usriX_usr_comment,
112 infoX->usriX_primary_group_id,
118 infoX->usriX_country_code,
125 /****************************************************************
126 ****************************************************************/
128 static NTSTATUS construct_USER_INFO_X(uint32_t level,
130 struct USER_INFO_X *uX)
132 struct USER_INFO_0 *u0 = NULL;
133 struct USER_INFO_1 *u1 = NULL;
134 struct USER_INFO_2 *u2 = NULL;
135 struct USER_INFO_1003 *u1003 = NULL;
136 struct USER_INFO_1006 *u1006 = NULL;
137 struct USER_INFO_1007 *u1007 = NULL;
138 struct USER_INFO_1009 *u1009 = NULL;
139 struct USER_INFO_1011 *u1011 = NULL;
140 struct USER_INFO_1012 *u1012 = NULL;
141 struct USER_INFO_1014 *u1014 = NULL;
142 struct USER_INFO_1024 *u1024 = NULL;
143 struct USER_INFO_1051 *u1051 = NULL;
144 struct USER_INFO_1052 *u1052 = NULL;
145 struct USER_INFO_1053 *u1053 = NULL;
147 if (!buffer || !uX) {
148 return NT_STATUS_INVALID_PARAMETER;
155 u0 = (struct USER_INFO_0 *)buffer;
156 uX->usriX_name = u0->usri0_name;
159 u1 = (struct USER_INFO_1 *)buffer;
160 uX->usriX_name = u1->usri1_name;
161 uX->usriX_password = u1->usri1_password;
162 uX->usriX_password_age = u1->usri1_password_age;
163 uX->usriX_priv = u1->usri1_priv;
164 uX->usriX_home_dir = u1->usri1_home_dir;
165 uX->usriX_comment = u1->usri1_comment;
166 uX->usriX_flags = u1->usri1_flags;
167 uX->usriX_script_path = u1->usri1_script_path;
170 u2 = (struct USER_INFO_2 *)buffer;
171 uX->usriX_name = u2->usri2_name;
172 uX->usriX_password = u2->usri2_password;
173 uX->usriX_password_age = u2->usri2_password_age;
174 uX->usriX_priv = u2->usri2_priv;
175 uX->usriX_home_dir = u2->usri2_home_dir;
176 uX->usriX_comment = u2->usri2_comment;
177 uX->usriX_flags = u2->usri2_flags;
178 uX->usriX_script_path = u2->usri2_script_path;
179 uX->usriX_auth_flags = u2->usri2_auth_flags;
180 uX->usriX_full_name = u2->usri2_full_name;
181 uX->usriX_usr_comment = u2->usri2_usr_comment;
182 uX->usriX_parms = u2->usri2_parms;
183 uX->usriX_workstations = u2->usri2_workstations;
184 uX->usriX_last_logon = u2->usri2_last_logon;
185 uX->usriX_last_logoff = u2->usri2_last_logoff;
186 uX->usriX_acct_expires = u2->usri2_acct_expires;
187 uX->usriX_max_storage = u2->usri2_max_storage;
188 uX->usriX_units_per_week= u2->usri2_units_per_week;
189 uX->usriX_logon_hours = u2->usri2_logon_hours;
190 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
191 uX->usriX_num_logons = u2->usri2_num_logons;
192 uX->usriX_logon_server = u2->usri2_logon_server;
193 uX->usriX_country_code = u2->usri2_country_code;
194 uX->usriX_code_page = u2->usri2_code_page;
197 u1003 = (struct USER_INFO_1003 *)buffer;
198 uX->usriX_password = u1003->usri1003_password;
201 u1006 = (struct USER_INFO_1006 *)buffer;
202 uX->usriX_home_dir = u1006->usri1006_home_dir;
205 u1007 = (struct USER_INFO_1007 *)buffer;
206 uX->usriX_comment = u1007->usri1007_comment;
209 u1009 = (struct USER_INFO_1009 *)buffer;
210 uX->usriX_script_path = u1009->usri1009_script_path;
213 u1011 = (struct USER_INFO_1011 *)buffer;
214 uX->usriX_full_name = u1011->usri1011_full_name;
217 u1012 = (struct USER_INFO_1012 *)buffer;
218 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
221 u1014 = (struct USER_INFO_1014 *)buffer;
222 uX->usriX_workstations = u1014->usri1014_workstations;
225 u1024 = (struct USER_INFO_1024 *)buffer;
226 uX->usriX_country_code = u1024->usri1024_country_code;
229 u1051 = (struct USER_INFO_1051 *)buffer;
230 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
233 u1052 = (struct USER_INFO_1052 *)buffer;
234 uX->usriX_profile = u1052->usri1052_profile;
237 u1053 = (struct USER_INFO_1053 *)buffer;
238 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
243 return NT_STATUS_INVALID_INFO_CLASS;
249 /****************************************************************
250 ****************************************************************/
252 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
253 struct rpc_pipe_client *pipe_cli,
254 DATA_BLOB *session_key,
255 struct policy_handle *user_handle,
256 struct USER_INFO_X *uX)
258 union samr_UserInfo user_info;
259 struct samr_UserInfo21 info21;
263 return NT_STATUS_INVALID_PARAMETER;
266 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
268 ZERO_STRUCT(user_info);
270 if (uX->usriX_password) {
272 user_info.info25.info = info21;
274 init_samr_CryptPasswordEx(uX->usriX_password,
276 &user_info.info25.password);
278 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
283 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
285 user_info.info23.info = info21;
287 init_samr_CryptPassword(uX->usriX_password,
289 &user_info.info23.password);
291 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
298 user_info.info21 = info21;
300 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
309 /****************************************************************
310 ****************************************************************/
312 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
313 struct NetUserAdd *r)
315 struct cli_state *cli = NULL;
316 struct rpc_pipe_client *pipe_cli = NULL;
319 POLICY_HND connect_handle, domain_handle, user_handle;
320 struct lsa_String lsa_account_name;
321 struct dom_sid2 *domain_sid = NULL;
322 union samr_UserInfo *user_info = NULL;
323 struct samr_PwInfo pw_info;
324 uint32_t access_granted = 0;
326 struct USER_INFO_X uX;
328 ZERO_STRUCT(connect_handle);
329 ZERO_STRUCT(domain_handle);
330 ZERO_STRUCT(user_handle);
333 return WERR_INVALID_PARAM;
336 switch (r->in.level) {
343 werr = WERR_NOT_SUPPORTED;
347 werr = libnetapi_open_pipe(ctx, r->in.server_name,
348 &ndr_table_samr.syntax_id,
351 if (!W_ERROR_IS_OK(werr)) {
355 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
356 if (!NT_STATUS_IS_OK(status)) {
357 werr = ntstatus_to_werror(status);
361 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
362 SAMR_ACCESS_ENUM_DOMAINS |
363 SAMR_ACCESS_OPEN_DOMAIN,
364 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
365 SAMR_DOMAIN_ACCESS_CREATE_USER |
366 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
370 if (!W_ERROR_IS_OK(werr)) {
374 init_lsa_String(&lsa_account_name, uX.usriX_name);
376 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
382 SAMR_USER_ACCESS_SET_PASSWORD |
383 SAMR_USER_ACCESS_SET_ATTRIBUTES |
384 SAMR_USER_ACCESS_GET_ATTRIBUTES,
388 if (!NT_STATUS_IS_OK(status)) {
389 werr = ntstatus_to_werror(status);
393 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
397 if (!NT_STATUS_IS_OK(status)) {
398 werr = ntstatus_to_werror(status);
402 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
403 werr = WERR_INVALID_PARAM;
407 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
410 if (!NT_STATUS_IS_OK(status)) {
411 werr = ntstatus_to_werror(status);
415 uX.usriX_flags |= ACB_NORMAL;
417 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
418 &cli->user_session_key,
421 if (!NT_STATUS_IS_OK(status)) {
422 werr = ntstatus_to_werror(status);
430 rpccli_samr_DeleteUser(pipe_cli, ctx,
438 if (is_valid_policy_hnd(&user_handle)) {
439 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
442 if (ctx->disable_policy_handle_cache) {
443 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
444 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
450 /****************************************************************
451 ****************************************************************/
453 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
454 struct NetUserAdd *r)
456 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
459 /****************************************************************
460 ****************************************************************/
462 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
463 struct NetUserDel *r)
465 struct cli_state *cli = NULL;
466 struct rpc_pipe_client *pipe_cli = NULL;
469 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
470 struct lsa_String lsa_account_name;
471 struct samr_Ids user_rids, name_types;
472 struct dom_sid2 *domain_sid = NULL;
473 struct dom_sid2 user_sid;
475 ZERO_STRUCT(connect_handle);
476 ZERO_STRUCT(builtin_handle);
477 ZERO_STRUCT(domain_handle);
478 ZERO_STRUCT(user_handle);
480 werr = libnetapi_open_pipe(ctx, r->in.server_name,
481 &ndr_table_samr.syntax_id,
485 if (!W_ERROR_IS_OK(werr)) {
489 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
490 SAMR_ACCESS_ENUM_DOMAINS |
491 SAMR_ACCESS_OPEN_DOMAIN,
492 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
496 if (!W_ERROR_IS_OK(werr)) {
500 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
502 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
503 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
505 if (!NT_STATUS_IS_OK(status)) {
506 werr = ntstatus_to_werror(status);
510 init_lsa_String(&lsa_account_name, r->in.user_name);
512 status = rpccli_samr_LookupNames(pipe_cli, ctx,
518 if (!NT_STATUS_IS_OK(status)) {
519 werr = ntstatus_to_werror(status);
523 status = rpccli_samr_OpenUser(pipe_cli, ctx,
525 STD_RIGHT_DELETE_ACCESS,
528 if (!NT_STATUS_IS_OK(status)) {
529 werr = ntstatus_to_werror(status);
533 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
535 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
538 if (!NT_STATUS_IS_OK(status)) {
539 werr = ntstatus_to_werror(status);
543 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
545 if (!NT_STATUS_IS_OK(status)) {
546 werr = ntstatus_to_werror(status);
557 if (is_valid_policy_hnd(&user_handle)) {
558 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
561 if (ctx->disable_policy_handle_cache) {
562 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
563 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
564 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
570 /****************************************************************
571 ****************************************************************/
573 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
574 struct NetUserDel *r)
576 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
579 /****************************************************************
580 ****************************************************************/
582 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
583 struct rpc_pipe_client *pipe_cli,
584 struct policy_handle *domain_handle,
585 struct policy_handle *builtin_handle,
586 const char *user_name,
589 struct samr_UserInfo21 **info21,
590 struct sec_desc_buf **sec_desc)
594 struct policy_handle user_handle;
595 union samr_UserInfo *user_info = NULL;
596 struct samr_RidWithAttributeArray *rid_array = NULL;
597 uint32_t access_mask = SEC_STD_READ_CONTROL |
598 SAMR_USER_ACCESS_GET_ATTRIBUTES |
599 SAMR_USER_ACCESS_GET_NAME_ETC;
601 ZERO_STRUCT(user_handle);
614 return NT_STATUS_INVALID_LEVEL;
621 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
626 if (!NT_STATUS_IS_OK(status)) {
630 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
634 if (!NT_STATUS_IS_OK(status)) {
638 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
642 if (!NT_STATUS_IS_OK(status)) {
647 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
650 if (!NT_STATUS_IS_OK(status)) {
655 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
659 if (!NT_STATUS_IS_OK(status)) {
665 *info21 = &user_info->info21;
668 if (is_valid_policy_hnd(&user_handle)) {
669 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
675 /****************************************************************
676 ****************************************************************/
678 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
680 uint32_t fl = UF_SCRIPT; /* god knows why */
682 fl |= ads_acb2uf(acb);
687 /****************************************************************
688 ****************************************************************/
690 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
691 struct rpc_pipe_client *pipe_cli,
692 struct dom_sid *domain_sid,
693 struct policy_handle *domain_handle,
694 struct policy_handle *builtin_handle,
695 const char *user_name,
699 uint32_t *num_entries)
703 struct samr_UserInfo21 *info21 = NULL;
704 struct sec_desc_buf *sec_desc = NULL;
707 struct USER_INFO_0 info0;
708 struct USER_INFO_10 info10;
709 struct USER_INFO_20 info20;
710 struct USER_INFO_23 info23;
723 return NT_STATUS_INVALID_LEVEL;
727 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
728 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
730 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
731 (struct USER_INFO_0 **)buffer, num_entries);
736 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
745 if (!NT_STATUS_IS_OK(status)) {
751 info10.usri10_name = talloc_strdup(mem_ctx,
752 info21->account_name.string);
753 NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
755 info10.usri10_comment = talloc_strdup(mem_ctx,
756 info21->description.string);
758 info10.usri10_full_name = talloc_strdup(mem_ctx,
759 info21->full_name.string);
761 info10.usri10_usr_comment = talloc_strdup(mem_ctx,
762 info21->comment.string);
764 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
765 (struct USER_INFO_10 **)buffer, num_entries);
770 info20.usri20_name = talloc_strdup(mem_ctx,
771 info21->account_name.string);
772 NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
774 info20.usri20_comment = talloc_strdup(mem_ctx,
775 info21->description.string);
777 info20.usri20_full_name = talloc_strdup(mem_ctx,
778 info21->full_name.string);
780 info20.usri20_flags =
781 samr_acb_flags_to_netapi_flags(info21->acct_flags);
782 info20.usri20_user_id = rid;
784 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
785 (struct USER_INFO_20 **)buffer, num_entries);
789 info23.usri23_name = talloc_strdup(mem_ctx,
790 info21->account_name.string);
791 NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
793 info23.usri23_comment = talloc_strdup(mem_ctx,
794 info21->description.string);
796 info23.usri23_full_name = talloc_strdup(mem_ctx,
797 info21->full_name.string);
799 info23.usri23_flags =
800 samr_acb_flags_to_netapi_flags(info21->acct_flags);
802 if (!sid_compose(&sid, domain_sid, rid)) {
803 return NT_STATUS_NO_MEMORY;
806 info23.usri23_user_sid =
807 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
809 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
810 (struct USER_INFO_23 **)buffer, num_entries);
818 /****************************************************************
819 ****************************************************************/
821 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
822 struct NetUserEnum *r)
824 struct cli_state *cli = NULL;
825 struct rpc_pipe_client *pipe_cli = NULL;
826 struct policy_handle connect_handle;
827 struct dom_sid2 *domain_sid = NULL;
828 struct policy_handle domain_handle;
829 struct samr_SamArray *sam = NULL;
830 uint32_t filter = ACB_NORMAL;
832 uint32_t entries_read = 0;
834 NTSTATUS status = NT_STATUS_OK;
837 ZERO_STRUCT(connect_handle);
838 ZERO_STRUCT(domain_handle);
840 if (!r->out.buffer) {
841 return WERR_INVALID_PARAM;
844 *r->out.buffer = NULL;
845 *r->out.entries_read = 0;
847 switch (r->in.level) {
858 return WERR_NOT_SUPPORTED;
861 werr = libnetapi_open_pipe(ctx, r->in.server_name,
862 &ndr_table_samr.syntax_id,
865 if (!W_ERROR_IS_OK(werr)) {
869 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
870 SAMR_ACCESS_ENUM_DOMAINS |
871 SAMR_ACCESS_OPEN_DOMAIN,
872 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
873 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
874 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
878 if (!W_ERROR_IS_OK(werr)) {
882 switch (r->in.filter) {
883 case FILTER_NORMAL_ACCOUNT:
886 case FILTER_TEMP_DUPLICATE_ACCOUNT:
887 filter = ACB_TEMPDUP;
889 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
890 filter = ACB_DOMTRUST;
892 case FILTER_WORKSTATION_TRUST_ACCOUNT:
893 filter = ACB_WSTRUST;
895 case FILTER_SERVER_TRUST_ACCOUNT:
896 filter = ACB_SVRTRUST;
902 status = rpccli_samr_EnumDomainUsers(pipe_cli,
910 werr = ntstatus_to_werror(status);
911 if (NT_STATUS_IS_ERR(status)) {
915 for (i=0; i < sam->count; i++) {
917 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
920 NULL, /*&builtin_handle, */
921 sam->entries[i].name.string,
925 r->out.entries_read);
926 if (!NT_STATUS_IS_OK(status)) {
927 werr = ntstatus_to_werror(status);
938 if (NT_STATUS_IS_OK(status) ||
939 NT_STATUS_IS_ERR(status)) {
941 if (ctx->disable_policy_handle_cache) {
942 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
943 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
950 /****************************************************************
951 ****************************************************************/
953 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
954 struct NetUserEnum *r)
956 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
959 /****************************************************************
960 ****************************************************************/
962 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
963 struct samr_DispInfoGeneral *info,
964 uint32_t *entries_read,
967 struct NET_DISPLAY_USER *user = NULL;
970 user = TALLOC_ZERO_ARRAY(mem_ctx,
971 struct NET_DISPLAY_USER,
973 W_ERROR_HAVE_NO_MEMORY(user);
975 for (i = 0; i < info->count; i++) {
976 user[i].usri1_name = talloc_strdup(mem_ctx,
977 info->entries[i].account_name.string);
978 user[i].usri1_comment = talloc_strdup(mem_ctx,
979 info->entries[i].description.string);
980 user[i].usri1_flags =
981 info->entries[i].acct_flags;
982 user[i].usri1_full_name = talloc_strdup(mem_ctx,
983 info->entries[i].full_name.string);
984 user[i].usri1_user_id =
985 info->entries[i].rid;
986 user[i].usri1_next_index =
987 info->entries[i].idx;
989 if (!user[i].usri1_name) {
994 *buffer = talloc_memdup(mem_ctx, user,
995 sizeof(struct NET_DISPLAY_USER) * info->count);
996 W_ERROR_HAVE_NO_MEMORY(*buffer);
998 *entries_read = info->count;
1003 /****************************************************************
1004 ****************************************************************/
1006 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1007 struct samr_DispInfoFull *info,
1008 uint32_t *entries_read,
1011 struct NET_DISPLAY_MACHINE *machine = NULL;
1014 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1015 struct NET_DISPLAY_MACHINE,
1017 W_ERROR_HAVE_NO_MEMORY(machine);
1019 for (i = 0; i < info->count; i++) {
1020 machine[i].usri2_name = talloc_strdup(mem_ctx,
1021 info->entries[i].account_name.string);
1022 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1023 info->entries[i].description.string);
1024 machine[i].usri2_flags =
1025 info->entries[i].acct_flags;
1026 machine[i].usri2_user_id =
1027 info->entries[i].rid;
1028 machine[i].usri2_next_index =
1029 info->entries[i].idx;
1031 if (!machine[i].usri2_name) {
1036 *buffer = talloc_memdup(mem_ctx, machine,
1037 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1038 W_ERROR_HAVE_NO_MEMORY(*buffer);
1040 *entries_read = info->count;
1045 /****************************************************************
1046 ****************************************************************/
1048 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1049 struct samr_DispInfoFullGroups *info,
1050 uint32_t *entries_read,
1053 struct NET_DISPLAY_GROUP *group = NULL;
1056 group = TALLOC_ZERO_ARRAY(mem_ctx,
1057 struct NET_DISPLAY_GROUP,
1059 W_ERROR_HAVE_NO_MEMORY(group);
1061 for (i = 0; i < info->count; i++) {
1062 group[i].grpi3_name = talloc_strdup(mem_ctx,
1063 info->entries[i].account_name.string);
1064 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1065 info->entries[i].description.string);
1066 group[i].grpi3_group_id =
1067 info->entries[i].rid;
1068 group[i].grpi3_attributes =
1069 info->entries[i].acct_flags;
1070 group[i].grpi3_next_index =
1071 info->entries[i].idx;
1073 if (!group[i].grpi3_name) {
1078 *buffer = talloc_memdup(mem_ctx, group,
1079 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1080 W_ERROR_HAVE_NO_MEMORY(*buffer);
1082 *entries_read = info->count;
1088 /****************************************************************
1089 ****************************************************************/
1091 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1092 union samr_DispInfo *info,
1094 uint32_t *entries_read,
1099 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1104 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1109 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1114 return WERR_UNKNOWN_LEVEL;
1120 /****************************************************************
1121 ****************************************************************/
1123 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1124 struct NetQueryDisplayInformation *r)
1126 struct cli_state *cli = NULL;
1127 struct rpc_pipe_client *pipe_cli = NULL;
1128 struct policy_handle connect_handle;
1129 struct dom_sid2 *domain_sid = NULL;
1130 struct policy_handle domain_handle;
1131 union samr_DispInfo info;
1133 uint32_t total_size = 0;
1134 uint32_t returned_size = 0;
1136 NTSTATUS status = NT_STATUS_OK;
1139 ZERO_STRUCT(connect_handle);
1140 ZERO_STRUCT(domain_handle);
1142 switch (r->in.level) {
1148 return WERR_UNKNOWN_LEVEL;
1151 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1152 &ndr_table_samr.syntax_id,
1155 if (!W_ERROR_IS_OK(werr)) {
1159 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1160 SAMR_ACCESS_ENUM_DOMAINS |
1161 SAMR_ACCESS_OPEN_DOMAIN,
1162 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1163 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1164 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1168 if (!W_ERROR_IS_OK(werr)) {
1172 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1177 r->in.entries_requested,
1182 if (!NT_STATUS_IS_OK(status)) {
1183 werr = ntstatus_to_werror(status);
1187 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1189 r->out.entries_read,
1197 if (NT_STATUS_IS_OK(status) ||
1198 NT_STATUS_IS_ERR(status)) {
1200 if (ctx->disable_policy_handle_cache) {
1201 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1202 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1210 /****************************************************************
1211 ****************************************************************/
1214 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1215 struct NetQueryDisplayInformation *r)
1217 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1220 /****************************************************************
1221 ****************************************************************/
1223 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1224 struct NetUserChangePassword *r)
1226 return WERR_NOT_SUPPORTED;
1229 /****************************************************************
1230 ****************************************************************/
1232 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1233 struct NetUserChangePassword *r)
1235 return WERR_NOT_SUPPORTED;
1238 /****************************************************************
1239 ****************************************************************/
1241 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1242 struct NetUserGetInfo *r)
1244 struct cli_state *cli = NULL;
1245 struct rpc_pipe_client *pipe_cli = NULL;
1249 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1250 struct lsa_String lsa_account_name;
1251 struct dom_sid2 *domain_sid = NULL;
1252 struct samr_Ids user_rids, name_types;
1253 uint32_t num_entries = 0;
1255 ZERO_STRUCT(connect_handle);
1256 ZERO_STRUCT(domain_handle);
1257 ZERO_STRUCT(builtin_handle);
1258 ZERO_STRUCT(user_handle);
1260 if (!r->out.buffer) {
1261 return WERR_INVALID_PARAM;
1264 switch (r->in.level) {
1272 werr = WERR_NOT_SUPPORTED;
1276 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1277 &ndr_table_samr.syntax_id,
1280 if (!W_ERROR_IS_OK(werr)) {
1284 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1285 SAMR_ACCESS_ENUM_DOMAINS |
1286 SAMR_ACCESS_OPEN_DOMAIN,
1287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1291 if (!W_ERROR_IS_OK(werr)) {
1295 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1296 SAMR_ACCESS_ENUM_DOMAINS |
1297 SAMR_ACCESS_OPEN_DOMAIN,
1298 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1299 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1302 if (!W_ERROR_IS_OK(werr)) {
1306 init_lsa_String(&lsa_account_name, r->in.user_name);
1308 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1314 if (!NT_STATUS_IS_OK(status)) {
1315 werr = ntstatus_to_werror(status);
1319 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1328 if (!NT_STATUS_IS_OK(status)) {
1329 werr = ntstatus_to_werror(status);
1338 if (is_valid_policy_hnd(&user_handle)) {
1339 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1342 if (ctx->disable_policy_handle_cache) {
1343 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1344 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1350 /****************************************************************
1351 ****************************************************************/
1353 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1354 struct NetUserGetInfo *r)
1356 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1359 /****************************************************************
1360 ****************************************************************/
1362 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1363 struct NetUserSetInfo *r)
1365 struct cli_state *cli = NULL;
1366 struct rpc_pipe_client *pipe_cli = NULL;
1370 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1371 struct lsa_String lsa_account_name;
1372 struct dom_sid2 *domain_sid = NULL;
1373 struct samr_Ids user_rids, name_types;
1374 uint32_t user_mask = 0;
1376 struct USER_INFO_X uX;
1378 ZERO_STRUCT(connect_handle);
1379 ZERO_STRUCT(domain_handle);
1380 ZERO_STRUCT(builtin_handle);
1381 ZERO_STRUCT(user_handle);
1383 if (!r->in.buffer) {
1384 return WERR_INVALID_PARAM;
1387 switch (r->in.level) {
1390 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1399 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1403 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1405 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1406 SAMR_USER_ACCESS_GET_GROUPS;
1419 werr = WERR_NOT_SUPPORTED;
1422 werr = WERR_UNKNOWN_LEVEL;
1426 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1427 &ndr_table_samr.syntax_id,
1430 if (!W_ERROR_IS_OK(werr)) {
1434 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1435 SAMR_ACCESS_ENUM_DOMAINS |
1436 SAMR_ACCESS_OPEN_DOMAIN,
1437 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1438 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1442 if (!W_ERROR_IS_OK(werr)) {
1446 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1447 SAMR_ACCESS_ENUM_DOMAINS |
1448 SAMR_ACCESS_OPEN_DOMAIN,
1449 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1450 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1453 if (!W_ERROR_IS_OK(werr)) {
1457 init_lsa_String(&lsa_account_name, r->in.user_name);
1459 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1465 if (!NT_STATUS_IS_OK(status)) {
1466 werr = ntstatus_to_werror(status);
1470 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1475 if (!NT_STATUS_IS_OK(status)) {
1476 werr = ntstatus_to_werror(status);
1480 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 werr = ntstatus_to_werror(status);
1486 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1487 &cli->user_session_key,
1490 if (!NT_STATUS_IS_OK(status)) {
1491 werr = ntstatus_to_werror(status);
1502 if (is_valid_policy_hnd(&user_handle)) {
1503 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1506 if (ctx->disable_policy_handle_cache) {
1507 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1508 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1509 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1515 /****************************************************************
1516 ****************************************************************/
1518 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1519 struct NetUserSetInfo *r)
1521 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1524 /****************************************************************
1525 ****************************************************************/
1527 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1528 struct rpc_pipe_client *pipe_cli,
1529 struct policy_handle *domain_handle,
1530 struct samr_DomInfo1 *info1,
1531 struct samr_DomInfo3 *info3,
1532 struct samr_DomInfo5 *info5,
1533 struct samr_DomInfo6 *info6,
1534 struct samr_DomInfo7 *info7,
1535 struct samr_DomInfo12 *info12)
1538 union samr_DomainInfo *dom_info = NULL;
1541 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1545 NT_STATUS_NOT_OK_RETURN(status);
1547 *info1 = dom_info->info1;
1551 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1555 NT_STATUS_NOT_OK_RETURN(status);
1557 *info3 = dom_info->info3;
1561 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1565 NT_STATUS_NOT_OK_RETURN(status);
1567 *info5 = dom_info->info5;
1571 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1575 NT_STATUS_NOT_OK_RETURN(status);
1577 *info6 = dom_info->info6;
1581 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1585 NT_STATUS_NOT_OK_RETURN(status);
1587 *info7 = dom_info->info7;
1591 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1595 NT_STATUS_NOT_OK_RETURN(status);
1597 *info12 = dom_info->info12;
1600 return NT_STATUS_OK;
1603 /****************************************************************
1604 ****************************************************************/
1606 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1607 struct rpc_pipe_client *pipe_cli,
1608 struct policy_handle *domain_handle,
1609 struct USER_MODALS_INFO_0 *info0)
1612 struct samr_DomInfo1 dom_info1;
1613 struct samr_DomInfo3 dom_info3;
1615 ZERO_STRUCTP(info0);
1617 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1626 NT_STATUS_NOT_OK_RETURN(status);
1628 info0->usrmod0_min_passwd_len =
1629 dom_info1.min_password_length;
1630 info0->usrmod0_max_passwd_age =
1631 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1632 info0->usrmod0_min_passwd_age =
1633 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
1634 info0->usrmod0_password_hist_len =
1635 dom_info1.password_history_length;
1637 info0->usrmod0_force_logoff =
1638 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
1640 return NT_STATUS_OK;
1643 /****************************************************************
1644 ****************************************************************/
1646 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
1647 struct rpc_pipe_client *pipe_cli,
1648 struct policy_handle *domain_handle,
1649 struct USER_MODALS_INFO_1 *info1)
1652 struct samr_DomInfo6 dom_info6;
1653 struct samr_DomInfo7 dom_info7;
1655 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1664 NT_STATUS_NOT_OK_RETURN(status);
1666 info1->usrmod1_primary =
1667 talloc_strdup(mem_ctx, dom_info6.primary.string);
1669 info1->usrmod1_role = dom_info7.role;
1671 return NT_STATUS_OK;
1674 /****************************************************************
1675 ****************************************************************/
1677 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
1678 struct rpc_pipe_client *pipe_cli,
1679 struct policy_handle *domain_handle,
1680 struct dom_sid *domain_sid,
1681 struct USER_MODALS_INFO_2 *info2)
1684 struct samr_DomInfo5 dom_info5;
1686 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1695 NT_STATUS_NOT_OK_RETURN(status);
1697 info2->usrmod2_domain_name =
1698 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
1699 info2->usrmod2_domain_id =
1700 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
1702 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
1703 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
1705 return NT_STATUS_OK;
1708 /****************************************************************
1709 ****************************************************************/
1711 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
1712 struct rpc_pipe_client *pipe_cli,
1713 struct policy_handle *domain_handle,
1714 struct USER_MODALS_INFO_3 *info3)
1717 struct samr_DomInfo12 dom_info12;
1719 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1728 NT_STATUS_NOT_OK_RETURN(status);
1730 info3->usrmod3_lockout_duration =
1731 nt_time_to_unix_abs(&dom_info12.lockout_duration);
1732 info3->usrmod3_lockout_observation_window =
1733 nt_time_to_unix_abs(&dom_info12.lockout_window);
1734 info3->usrmod3_lockout_threshold =
1735 dom_info12.lockout_threshold;
1737 return NT_STATUS_OK;
1740 /****************************************************************
1741 ****************************************************************/
1743 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
1744 struct rpc_pipe_client *pipe_cli,
1746 struct policy_handle *domain_handle,
1747 struct dom_sid *domain_sid,
1752 struct USER_MODALS_INFO_0 info0;
1753 struct USER_MODALS_INFO_1 info1;
1754 struct USER_MODALS_INFO_2 info2;
1755 struct USER_MODALS_INFO_3 info3;
1758 return ERROR_INSUFFICIENT_BUFFER;
1763 status = query_USER_MODALS_INFO_0(mem_ctx,
1767 NT_STATUS_NOT_OK_RETURN(status);
1769 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
1774 status = query_USER_MODALS_INFO_1(mem_ctx,
1778 NT_STATUS_NOT_OK_RETURN(status);
1780 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
1784 status = query_USER_MODALS_INFO_2(mem_ctx,
1789 NT_STATUS_NOT_OK_RETURN(status);
1791 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
1795 status = query_USER_MODALS_INFO_3(mem_ctx,
1799 NT_STATUS_NOT_OK_RETURN(status);
1801 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
1808 NT_STATUS_HAVE_NO_MEMORY(*buffer);
1810 return NT_STATUS_OK;
1813 /****************************************************************
1814 ****************************************************************/
1816 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
1817 struct NetUserModalsGet *r)
1819 struct cli_state *cli = NULL;
1820 struct rpc_pipe_client *pipe_cli = NULL;
1824 struct policy_handle connect_handle, domain_handle;
1825 struct dom_sid2 *domain_sid = NULL;
1826 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
1828 ZERO_STRUCT(connect_handle);
1829 ZERO_STRUCT(domain_handle);
1831 if (!r->out.buffer) {
1832 return WERR_INVALID_PARAM;
1835 switch (r->in.level) {
1837 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1838 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1842 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1845 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
1848 werr = WERR_UNKNOWN_LEVEL;
1852 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1853 &ndr_table_samr.syntax_id,
1856 if (!W_ERROR_IS_OK(werr)) {
1860 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1861 SAMR_ACCESS_ENUM_DOMAINS |
1862 SAMR_ACCESS_OPEN_DOMAIN,
1867 if (!W_ERROR_IS_OK(werr)) {
1874 /* 3: 12 (DomainInfo2) */
1876 status = query_USER_MODALS_INFO_to_buffer(ctx,
1882 if (!NT_STATUS_IS_OK(status)) {
1883 werr = ntstatus_to_werror(status);
1892 if (ctx->disable_policy_handle_cache) {
1893 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1894 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1900 /****************************************************************
1901 ****************************************************************/
1903 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
1904 struct NetUserModalsGet *r)
1906 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
1909 /****************************************************************
1910 ****************************************************************/
1912 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1913 struct rpc_pipe_client *pipe_cli,
1914 struct policy_handle *domain_handle,
1915 struct samr_DomInfo1 *info1,
1916 struct samr_DomInfo3 *info3,
1917 struct samr_DomInfo12 *info12)
1920 union samr_DomainInfo dom_info;
1924 ZERO_STRUCT(dom_info);
1926 dom_info.info1 = *info1;
1928 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1932 NT_STATUS_NOT_OK_RETURN(status);
1937 ZERO_STRUCT(dom_info);
1939 dom_info.info3 = *info3;
1941 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1946 NT_STATUS_NOT_OK_RETURN(status);
1951 ZERO_STRUCT(dom_info);
1953 dom_info.info12 = *info12;
1955 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1960 NT_STATUS_NOT_OK_RETURN(status);
1963 return NT_STATUS_OK;
1966 /****************************************************************
1967 ****************************************************************/
1969 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1970 struct rpc_pipe_client *pipe_cli,
1971 struct policy_handle *domain_handle,
1972 struct USER_MODALS_INFO_0 *info0)
1975 struct samr_DomInfo1 dom_info_1;
1976 struct samr_DomInfo3 dom_info_3;
1978 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1987 NT_STATUS_NOT_OK_RETURN(status);
1989 dom_info_1.min_password_length =
1990 info0->usrmod0_min_passwd_len;
1991 dom_info_1.password_history_length =
1992 info0->usrmod0_password_hist_len;
1994 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1995 info0->usrmod0_max_passwd_age);
1996 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
1997 info0->usrmod0_min_passwd_age);
1999 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2000 info0->usrmod0_force_logoff);
2002 return set_USER_MODALS_INFO_rpc(mem_ctx,
2010 /****************************************************************
2011 ****************************************************************/
2013 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2014 struct rpc_pipe_client *pipe_cli,
2015 struct policy_handle *domain_handle,
2016 struct USER_MODALS_INFO_3 *info3)
2019 struct samr_DomInfo12 dom_info_12;
2021 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2030 NT_STATUS_NOT_OK_RETURN(status);
2032 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2033 info3->usrmod3_lockout_duration);
2034 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2035 info3->usrmod3_lockout_observation_window);
2036 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2038 return set_USER_MODALS_INFO_rpc(mem_ctx,
2046 /****************************************************************
2047 ****************************************************************/
2049 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2050 struct rpc_pipe_client *pipe_cli,
2051 struct policy_handle *domain_handle,
2052 struct USER_MODALS_INFO_1001 *info1001)
2055 struct samr_DomInfo1 dom_info_1;
2057 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2066 NT_STATUS_NOT_OK_RETURN(status);
2068 dom_info_1.min_password_length =
2069 info1001->usrmod1001_min_passwd_len;
2071 return set_USER_MODALS_INFO_rpc(mem_ctx,
2079 /****************************************************************
2080 ****************************************************************/
2082 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2083 struct rpc_pipe_client *pipe_cli,
2084 struct policy_handle *domain_handle,
2085 struct USER_MODALS_INFO_1002 *info1002)
2088 struct samr_DomInfo1 dom_info_1;
2090 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2099 NT_STATUS_NOT_OK_RETURN(status);
2101 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2102 info1002->usrmod1002_max_passwd_age);
2104 return set_USER_MODALS_INFO_rpc(mem_ctx,
2112 /****************************************************************
2113 ****************************************************************/
2115 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2116 struct rpc_pipe_client *pipe_cli,
2117 struct policy_handle *domain_handle,
2118 struct USER_MODALS_INFO_1003 *info1003)
2121 struct samr_DomInfo1 dom_info_1;
2123 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2132 NT_STATUS_NOT_OK_RETURN(status);
2134 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2135 info1003->usrmod1003_min_passwd_age);
2137 return set_USER_MODALS_INFO_rpc(mem_ctx,
2145 /****************************************************************
2146 ****************************************************************/
2148 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2149 struct rpc_pipe_client *pipe_cli,
2150 struct policy_handle *domain_handle,
2151 struct USER_MODALS_INFO_1004 *info1004)
2154 struct samr_DomInfo3 dom_info_3;
2156 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2165 NT_STATUS_NOT_OK_RETURN(status);
2167 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2168 info1004->usrmod1004_force_logoff);
2170 return set_USER_MODALS_INFO_rpc(mem_ctx,
2178 /****************************************************************
2179 ****************************************************************/
2181 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2182 struct rpc_pipe_client *pipe_cli,
2183 struct policy_handle *domain_handle,
2184 struct USER_MODALS_INFO_1005 *info1005)
2187 struct samr_DomInfo1 dom_info_1;
2189 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2198 NT_STATUS_NOT_OK_RETURN(status);
2200 dom_info_1.password_history_length =
2201 info1005->usrmod1005_password_hist_len;
2203 return set_USER_MODALS_INFO_rpc(mem_ctx,
2211 /****************************************************************
2212 ****************************************************************/
2214 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2215 struct rpc_pipe_client *pipe_cli,
2217 struct policy_handle *domain_handle,
2218 struct dom_sid *domain_sid,
2221 struct USER_MODALS_INFO_0 *info0;
2222 struct USER_MODALS_INFO_3 *info3;
2223 struct USER_MODALS_INFO_1001 *info1001;
2224 struct USER_MODALS_INFO_1002 *info1002;
2225 struct USER_MODALS_INFO_1003 *info1003;
2226 struct USER_MODALS_INFO_1004 *info1004;
2227 struct USER_MODALS_INFO_1005 *info1005;
2230 return ERROR_INSUFFICIENT_BUFFER;
2235 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2236 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2241 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2242 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2247 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2248 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2253 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2254 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2259 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2260 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2265 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2266 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2271 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2272 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2281 return NT_STATUS_OK;
2284 /****************************************************************
2285 ****************************************************************/
2287 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2288 struct NetUserModalsSet *r)
2290 struct cli_state *cli = NULL;
2291 struct rpc_pipe_client *pipe_cli = NULL;
2295 struct policy_handle connect_handle, domain_handle;
2296 struct dom_sid2 *domain_sid = NULL;
2297 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2299 ZERO_STRUCT(connect_handle);
2300 ZERO_STRUCT(domain_handle);
2302 if (!r->in.buffer) {
2303 return WERR_INVALID_PARAM;
2306 switch (r->in.level) {
2308 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2309 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2310 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2311 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2318 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2319 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2322 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2323 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2329 werr = WERR_NOT_SUPPORTED;
2332 werr = WERR_UNKNOWN_LEVEL;
2336 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2337 &ndr_table_samr.syntax_id,
2340 if (!W_ERROR_IS_OK(werr)) {
2344 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2345 SAMR_ACCESS_ENUM_DOMAINS |
2346 SAMR_ACCESS_OPEN_DOMAIN,
2351 if (!W_ERROR_IS_OK(werr)) {
2355 status = set_USER_MODALS_INFO_buffer(ctx,
2361 if (!NT_STATUS_IS_OK(status)) {
2362 werr = ntstatus_to_werror(status);
2371 if (ctx->disable_policy_handle_cache) {
2372 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2373 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2379 /****************************************************************
2380 ****************************************************************/
2382 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2383 struct NetUserModalsSet *r)
2385 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2388 /****************************************************************
2389 ****************************************************************/
2391 static NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2393 const char *group_name,
2394 uint32_t attributes,
2396 uint32_t *num_entries)
2398 struct GROUP_USERS_INFO_0 u0;
2399 struct GROUP_USERS_INFO_1 u1;
2403 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2404 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2406 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2407 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2410 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2411 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2413 u1.grui1_attributes = attributes;
2415 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2416 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2419 return NT_STATUS_INVALID_INFO_CLASS;
2422 return NT_STATUS_OK;
2425 /****************************************************************
2426 ****************************************************************/
2428 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2429 struct NetUserGetGroups *r)
2431 struct cli_state *cli = NULL;
2432 struct rpc_pipe_client *pipe_cli = NULL;
2433 struct policy_handle connect_handle, domain_handle, user_handle;
2434 struct lsa_String lsa_account_name;
2435 struct dom_sid2 *domain_sid = NULL;
2436 struct samr_Ids user_rids, name_types;
2437 struct samr_RidWithAttributeArray *rid_array = NULL;
2438 struct lsa_Strings names;
2439 struct samr_Ids types;
2440 uint32_t *rids = NULL;
2443 uint32_t entries_read = 0;
2445 NTSTATUS status = NT_STATUS_OK;
2448 ZERO_STRUCT(connect_handle);
2449 ZERO_STRUCT(domain_handle);
2451 if (!r->out.buffer) {
2452 return WERR_INVALID_PARAM;
2455 *r->out.buffer = NULL;
2456 *r->out.entries_read = 0;
2458 switch (r->in.level) {
2463 return WERR_UNKNOWN_LEVEL;
2466 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2467 &ndr_table_samr.syntax_id,
2470 if (!W_ERROR_IS_OK(werr)) {
2474 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2475 SAMR_ACCESS_ENUM_DOMAINS |
2476 SAMR_ACCESS_OPEN_DOMAIN,
2477 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2481 if (!W_ERROR_IS_OK(werr)) {
2485 init_lsa_String(&lsa_account_name, r->in.user_name);
2487 status = rpccli_samr_LookupNames(pipe_cli, ctx,
2493 if (!NT_STATUS_IS_OK(status)) {
2494 werr = ntstatus_to_werror(status);
2498 status = rpccli_samr_OpenUser(pipe_cli, ctx,
2500 SAMR_USER_ACCESS_GET_GROUPS,
2503 if (!NT_STATUS_IS_OK(status)) {
2504 werr = ntstatus_to_werror(status);
2508 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2511 if (!NT_STATUS_IS_OK(status)) {
2512 werr = ntstatus_to_werror(status);
2516 rids = talloc_array(ctx, uint32_t, rid_array->count);
2522 for (i=0; i < rid_array->count; i++) {
2523 rids[i] = rid_array->rids[i].rid;
2526 status = rpccli_samr_LookupRids(pipe_cli, ctx,
2532 if (!NT_STATUS_IS_OK(status)) {
2533 werr = ntstatus_to_werror(status);
2537 for (i=0; i < rid_array->count; i++) {
2538 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2540 names.names[i].string,
2541 rid_array->rids[i].attributes,
2544 if (!NT_STATUS_IS_OK(status)) {
2545 werr = ntstatus_to_werror(status);
2550 if (r->out.entries_read) {
2551 *r->out.entries_read = entries_read;
2553 if (r->out.total_entries) {
2554 *r->out.total_entries = entries_read;
2562 if (ctx->disable_policy_handle_cache) {
2563 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2564 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2570 /****************************************************************
2571 ****************************************************************/
2573 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2574 struct NetUserGetGroups *r)
2576 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);