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,
111 infoX->usriX_user_id,
112 infoX->usriX_primary_group_id,
116 infoX->usriX_bad_pw_count,
117 infoX->usriX_num_logons,
118 infoX->usriX_country_code,
119 infoX->usriX_code_page,
122 infoX->usriX_password_expired);
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_3 *u3 = NULL;
136 struct USER_INFO_1003 *u1003 = NULL;
137 struct USER_INFO_1006 *u1006 = NULL;
138 struct USER_INFO_1007 *u1007 = NULL;
139 struct USER_INFO_1009 *u1009 = NULL;
140 struct USER_INFO_1011 *u1011 = NULL;
141 struct USER_INFO_1012 *u1012 = NULL;
142 struct USER_INFO_1014 *u1014 = NULL;
143 struct USER_INFO_1024 *u1024 = NULL;
144 struct USER_INFO_1051 *u1051 = NULL;
145 struct USER_INFO_1052 *u1052 = NULL;
146 struct USER_INFO_1053 *u1053 = NULL;
148 if (!buffer || !uX) {
149 return NT_STATUS_INVALID_PARAMETER;
156 u0 = (struct USER_INFO_0 *)buffer;
157 uX->usriX_name = u0->usri0_name;
160 u1 = (struct USER_INFO_1 *)buffer;
161 uX->usriX_name = u1->usri1_name;
162 uX->usriX_password = u1->usri1_password;
163 uX->usriX_password_age = u1->usri1_password_age;
164 uX->usriX_priv = u1->usri1_priv;
165 uX->usriX_home_dir = u1->usri1_home_dir;
166 uX->usriX_comment = u1->usri1_comment;
167 uX->usriX_flags = u1->usri1_flags;
168 uX->usriX_script_path = u1->usri1_script_path;
171 u2 = (struct USER_INFO_2 *)buffer;
172 uX->usriX_name = u2->usri2_name;
173 uX->usriX_password = u2->usri2_password;
174 uX->usriX_password_age = u2->usri2_password_age;
175 uX->usriX_priv = u2->usri2_priv;
176 uX->usriX_home_dir = u2->usri2_home_dir;
177 uX->usriX_comment = u2->usri2_comment;
178 uX->usriX_flags = u2->usri2_flags;
179 uX->usriX_script_path = u2->usri2_script_path;
180 uX->usriX_auth_flags = u2->usri2_auth_flags;
181 uX->usriX_full_name = u2->usri2_full_name;
182 uX->usriX_usr_comment = u2->usri2_usr_comment;
183 uX->usriX_parms = u2->usri2_parms;
184 uX->usriX_workstations = u2->usri2_workstations;
185 uX->usriX_last_logon = u2->usri2_last_logon;
186 uX->usriX_last_logoff = u2->usri2_last_logoff;
187 uX->usriX_acct_expires = u2->usri2_acct_expires;
188 uX->usriX_max_storage = u2->usri2_max_storage;
189 uX->usriX_units_per_week= u2->usri2_units_per_week;
190 uX->usriX_logon_hours = u2->usri2_logon_hours;
191 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
192 uX->usriX_num_logons = u2->usri2_num_logons;
193 uX->usriX_logon_server = u2->usri2_logon_server;
194 uX->usriX_country_code = u2->usri2_country_code;
195 uX->usriX_code_page = u2->usri2_code_page;
198 u3 = (struct USER_INFO_3 *)buffer;
199 uX->usriX_name = u3->usri3_name;
200 uX->usriX_password_age = u3->usri3_password_age;
201 uX->usriX_priv = u3->usri3_priv;
202 uX->usriX_home_dir = u3->usri3_home_dir;
203 uX->usriX_comment = u3->usri3_comment;
204 uX->usriX_flags = u3->usri3_flags;
205 uX->usriX_script_path = u3->usri3_script_path;
206 uX->usriX_auth_flags = u3->usri3_auth_flags;
207 uX->usriX_full_name = u3->usri3_full_name;
208 uX->usriX_usr_comment = u3->usri3_usr_comment;
209 uX->usriX_parms = u3->usri3_parms;
210 uX->usriX_workstations = u3->usri3_workstations;
211 uX->usriX_last_logon = u3->usri3_last_logon;
212 uX->usriX_last_logoff = u3->usri3_last_logoff;
213 uX->usriX_acct_expires = u3->usri3_acct_expires;
214 uX->usriX_max_storage = u3->usri3_max_storage;
215 uX->usriX_units_per_week= u3->usri3_units_per_week;
216 uX->usriX_logon_hours = u3->usri3_logon_hours;
217 uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
218 uX->usriX_num_logons = u3->usri3_num_logons;
219 uX->usriX_logon_server = u3->usri3_logon_server;
220 uX->usriX_country_code = u3->usri3_country_code;
221 uX->usriX_code_page = u3->usri3_code_page;
222 uX->usriX_user_id = u3->usri3_user_id;
223 uX->usriX_primary_group_id = u3->usri3_primary_group_id;
224 uX->usriX_profile = u3->usri3_profile;
225 uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
226 uX->usriX_password_expired = u3->usri3_password_expired;
229 u1003 = (struct USER_INFO_1003 *)buffer;
230 uX->usriX_password = u1003->usri1003_password;
233 u1006 = (struct USER_INFO_1006 *)buffer;
234 uX->usriX_home_dir = u1006->usri1006_home_dir;
237 u1007 = (struct USER_INFO_1007 *)buffer;
238 uX->usriX_comment = u1007->usri1007_comment;
241 u1009 = (struct USER_INFO_1009 *)buffer;
242 uX->usriX_script_path = u1009->usri1009_script_path;
245 u1011 = (struct USER_INFO_1011 *)buffer;
246 uX->usriX_full_name = u1011->usri1011_full_name;
249 u1012 = (struct USER_INFO_1012 *)buffer;
250 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
253 u1014 = (struct USER_INFO_1014 *)buffer;
254 uX->usriX_workstations = u1014->usri1014_workstations;
257 u1024 = (struct USER_INFO_1024 *)buffer;
258 uX->usriX_country_code = u1024->usri1024_country_code;
261 u1051 = (struct USER_INFO_1051 *)buffer;
262 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
265 u1052 = (struct USER_INFO_1052 *)buffer;
266 uX->usriX_profile = u1052->usri1052_profile;
269 u1053 = (struct USER_INFO_1053 *)buffer;
270 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
274 return NT_STATUS_INVALID_INFO_CLASS;
280 /****************************************************************
281 ****************************************************************/
283 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
284 struct rpc_pipe_client *pipe_cli,
285 DATA_BLOB *session_key,
286 struct policy_handle *user_handle,
287 struct USER_INFO_X *uX)
289 union samr_UserInfo user_info;
290 struct samr_UserInfo21 info21;
294 return NT_STATUS_INVALID_PARAMETER;
297 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
299 ZERO_STRUCT(user_info);
301 if (uX->usriX_password) {
303 user_info.info25.info = info21;
305 init_samr_CryptPasswordEx(uX->usriX_password,
307 &user_info.info25.password);
309 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
314 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
316 user_info.info23.info = info21;
318 init_samr_CryptPassword(uX->usriX_password,
320 &user_info.info23.password);
322 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
329 user_info.info21 = info21;
331 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
340 /****************************************************************
341 ****************************************************************/
343 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
344 struct NetUserAdd *r)
346 struct cli_state *cli = NULL;
347 struct rpc_pipe_client *pipe_cli = NULL;
350 POLICY_HND connect_handle, domain_handle, user_handle;
351 struct lsa_String lsa_account_name;
352 struct dom_sid2 *domain_sid = NULL;
353 union samr_UserInfo *user_info = NULL;
354 struct samr_PwInfo pw_info;
355 uint32_t access_granted = 0;
357 struct USER_INFO_X uX;
359 ZERO_STRUCT(connect_handle);
360 ZERO_STRUCT(domain_handle);
361 ZERO_STRUCT(user_handle);
364 return WERR_INVALID_PARAM;
367 switch (r->in.level) {
374 werr = WERR_NOT_SUPPORTED;
378 werr = libnetapi_open_pipe(ctx, r->in.server_name,
379 &ndr_table_samr.syntax_id,
382 if (!W_ERROR_IS_OK(werr)) {
386 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
387 if (!NT_STATUS_IS_OK(status)) {
388 werr = ntstatus_to_werror(status);
392 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
393 SAMR_ACCESS_ENUM_DOMAINS |
394 SAMR_ACCESS_OPEN_DOMAIN,
395 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
396 SAMR_DOMAIN_ACCESS_CREATE_USER |
397 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
401 if (!W_ERROR_IS_OK(werr)) {
405 init_lsa_String(&lsa_account_name, uX.usriX_name);
407 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
413 SAMR_USER_ACCESS_SET_PASSWORD |
414 SAMR_USER_ACCESS_SET_ATTRIBUTES |
415 SAMR_USER_ACCESS_GET_ATTRIBUTES,
419 if (!NT_STATUS_IS_OK(status)) {
420 werr = ntstatus_to_werror(status);
424 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
428 if (!NT_STATUS_IS_OK(status)) {
429 werr = ntstatus_to_werror(status);
433 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
434 werr = WERR_INVALID_PARAM;
438 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
441 if (!NT_STATUS_IS_OK(status)) {
442 werr = ntstatus_to_werror(status);
446 uX.usriX_flags |= ACB_NORMAL;
448 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
449 &cli->user_session_key,
452 if (!NT_STATUS_IS_OK(status)) {
453 werr = ntstatus_to_werror(status);
461 rpccli_samr_DeleteUser(pipe_cli, ctx,
469 if (is_valid_policy_hnd(&user_handle)) {
470 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
473 if (ctx->disable_policy_handle_cache) {
474 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
475 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
481 /****************************************************************
482 ****************************************************************/
484 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
485 struct NetUserAdd *r)
487 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
490 /****************************************************************
491 ****************************************************************/
493 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
494 struct NetUserDel *r)
496 struct cli_state *cli = NULL;
497 struct rpc_pipe_client *pipe_cli = NULL;
500 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
501 struct lsa_String lsa_account_name;
502 struct samr_Ids user_rids, name_types;
503 struct dom_sid2 *domain_sid = NULL;
504 struct dom_sid2 user_sid;
506 ZERO_STRUCT(connect_handle);
507 ZERO_STRUCT(builtin_handle);
508 ZERO_STRUCT(domain_handle);
509 ZERO_STRUCT(user_handle);
511 werr = libnetapi_open_pipe(ctx, r->in.server_name,
512 &ndr_table_samr.syntax_id,
516 if (!W_ERROR_IS_OK(werr)) {
520 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
521 SAMR_ACCESS_ENUM_DOMAINS |
522 SAMR_ACCESS_OPEN_DOMAIN,
523 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
527 if (!W_ERROR_IS_OK(werr)) {
531 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
533 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
534 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
536 if (!NT_STATUS_IS_OK(status)) {
537 werr = ntstatus_to_werror(status);
541 init_lsa_String(&lsa_account_name, r->in.user_name);
543 status = rpccli_samr_LookupNames(pipe_cli, ctx,
549 if (!NT_STATUS_IS_OK(status)) {
550 werr = ntstatus_to_werror(status);
554 status = rpccli_samr_OpenUser(pipe_cli, ctx,
556 STD_RIGHT_DELETE_ACCESS,
559 if (!NT_STATUS_IS_OK(status)) {
560 werr = ntstatus_to_werror(status);
564 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
566 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
569 if (!NT_STATUS_IS_OK(status)) {
570 werr = ntstatus_to_werror(status);
574 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
576 if (!NT_STATUS_IS_OK(status)) {
577 werr = ntstatus_to_werror(status);
588 if (is_valid_policy_hnd(&user_handle)) {
589 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
592 if (ctx->disable_policy_handle_cache) {
593 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
594 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
595 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
601 /****************************************************************
602 ****************************************************************/
604 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
605 struct NetUserDel *r)
607 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
610 /****************************************************************
611 ****************************************************************/
613 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
614 struct rpc_pipe_client *pipe_cli,
615 struct policy_handle *domain_handle,
616 struct policy_handle *builtin_handle,
617 const char *user_name,
618 const struct dom_sid *domain_sid,
621 struct samr_UserInfo21 **info21,
622 struct sec_desc_buf **sec_desc,
623 uint32_t *auth_flag_p)
627 struct policy_handle user_handle;
628 union samr_UserInfo *user_info = NULL;
629 struct samr_RidWithAttributeArray *rid_array = NULL;
630 uint32_t access_mask = SEC_STD_READ_CONTROL |
631 SAMR_USER_ACCESS_GET_ATTRIBUTES |
632 SAMR_USER_ACCESS_GET_NAME_ETC;
634 ZERO_STRUCT(user_handle);
640 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
641 SAMR_USER_ACCESS_GET_GROUPS;
647 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
648 SAMR_USER_ACCESS_GET_GROUPS |
649 SAMR_USER_ACCESS_GET_LOCALE;
656 return NT_STATUS_INVALID_LEVEL;
663 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
668 if (!NT_STATUS_IS_OK(status)) {
672 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
676 if (!NT_STATUS_IS_OK(status)) {
680 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
684 if (!NT_STATUS_IS_OK(status)) {
688 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
690 struct lsa_SidArray sid_array;
691 struct samr_Ids alias_rids;
693 uint32_t auth_flag = 0;
696 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
699 if (!NT_STATUS_IS_OK(status)) {
703 sid_array.num_sids = rid_array->count + 1;
704 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
706 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
708 for (i=0; i<rid_array->count; i++) {
709 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
710 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
711 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
714 sid_compose(&sid, domain_sid, rid);
715 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
716 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
718 status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
722 if (!NT_STATUS_IS_OK(status)) {
726 for (i=0; i<alias_rids.count; i++) {
727 switch (alias_rids.ids[i]) {
728 case 550: /* Print Operators */
729 auth_flag |= AF_OP_PRINT;
731 case 549: /* Server Operators */
732 auth_flag |= AF_OP_SERVER;
734 case 548: /* Account Operators */
735 auth_flag |= AF_OP_ACCOUNTS;
743 *auth_flag_p = auth_flag;
747 *info21 = &user_info->info21;
750 if (is_valid_policy_hnd(&user_handle)) {
751 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
757 /****************************************************************
758 ****************************************************************/
760 static uint32_t samr_rid_to_priv_level(uint32_t rid)
763 case DOMAIN_RID_ADMINISTRATOR:
764 return USER_PRIV_ADMIN;
765 case DOMAIN_RID_GUEST:
766 return USER_PRIV_GUEST;
768 return USER_PRIV_USER;
772 /****************************************************************
773 ****************************************************************/
775 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
777 uint32_t fl = UF_SCRIPT; /* god knows why */
779 fl |= ads_acb2uf(acb);
784 /****************************************************************
785 ****************************************************************/
787 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
788 const struct samr_UserInfo21 *i21,
789 struct USER_INFO_1 *i)
792 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
793 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
794 i->usri1_password = NULL;
795 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
796 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
797 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
798 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
799 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
800 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
805 /****************************************************************
806 ****************************************************************/
808 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
809 const struct samr_UserInfo21 *i21,
811 struct USER_INFO_2 *i)
815 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
816 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
817 i->usri2_password = NULL;
818 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
819 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
820 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
821 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
822 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
823 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
824 i->usri2_auth_flags = auth_flag;
825 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
826 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
827 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
828 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
829 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
830 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
831 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
832 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
833 i->usri2_units_per_week = i21->logon_hours.units_per_week;
834 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
835 i->usri2_bad_pw_count = i21->bad_password_count;
836 i->usri2_num_logons = i21->logon_count;
837 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
838 i->usri2_country_code = i21->country_code;
839 i->usri2_code_page = i21->code_page;
844 /****************************************************************
845 ****************************************************************/
847 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
848 const struct samr_UserInfo21 *i21,
850 struct USER_INFO_3 *i)
854 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
855 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
856 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
857 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
858 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
859 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
860 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
861 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
862 i->usri3_auth_flags = auth_flag;
863 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
864 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
865 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
866 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
867 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
868 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
869 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
870 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
871 i->usri3_units_per_week = i21->logon_hours.units_per_week;
872 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
873 i->usri3_bad_pw_count = i21->bad_password_count;
874 i->usri3_num_logons = i21->logon_count;
875 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
876 i->usri3_country_code = i21->country_code;
877 i->usri3_code_page = i21->code_page;
878 i->usri3_user_id = i21->rid;
879 i->usri3_primary_group_id = i21->primary_gid;
880 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
881 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
882 i->usri3_password_expired = i21->password_expired;
887 /****************************************************************
888 ****************************************************************/
890 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
891 const struct samr_UserInfo21 *i21,
893 struct dom_sid *domain_sid,
894 struct USER_INFO_4 *i)
900 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
901 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
902 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
903 i->usri4_password = NULL;
904 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
905 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
906 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
907 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
908 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
909 i->usri4_auth_flags = auth_flag;
910 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
911 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
912 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
913 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
914 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
915 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
916 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
917 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
918 i->usri4_units_per_week = i21->logon_hours.units_per_week;
919 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
920 i->usri4_bad_pw_count = i21->bad_password_count;
921 i->usri4_num_logons = i21->logon_count;
922 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
923 i->usri4_country_code = i21->country_code;
924 i->usri4_code_page = i21->code_page;
925 if (!sid_compose(&sid, domain_sid, i21->rid)) {
926 return NT_STATUS_NO_MEMORY;
928 i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
929 i->usri4_primary_group_id = i21->primary_gid;
930 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
931 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
932 i->usri4_password_expired = i21->password_expired;
937 /****************************************************************
938 ****************************************************************/
940 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
941 const struct samr_UserInfo21 *i21,
942 struct USER_INFO_10 *i)
946 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
947 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
948 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
949 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
950 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
955 /****************************************************************
956 ****************************************************************/
958 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
959 const struct samr_UserInfo21 *i21,
961 struct USER_INFO_11 *i)
965 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
966 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
967 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
968 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
969 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
970 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
971 i->usri11_auth_flags = auth_flag;
972 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
973 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
974 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
975 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
976 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
977 i->usri11_bad_pw_count = i21->bad_password_count;
978 i->usri11_num_logons = i21->logon_count;
979 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
980 i->usri11_country_code = i21->country_code;
981 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
982 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
983 i->usri11_units_per_week = i21->logon_hours.units_per_week;
984 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
985 i->usri11_code_page = i21->code_page;
990 /****************************************************************
991 ****************************************************************/
993 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
994 const struct samr_UserInfo21 *i21,
995 struct USER_INFO_20 *i)
999 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1000 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1001 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1002 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1003 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1004 i->usri20_user_id = i21->rid;
1006 return NT_STATUS_OK;
1009 /****************************************************************
1010 ****************************************************************/
1012 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1013 const struct samr_UserInfo21 *i21,
1014 struct dom_sid *domain_sid,
1015 struct USER_INFO_23 *i)
1021 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1022 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1023 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1024 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1025 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1026 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1027 return NT_STATUS_NO_MEMORY;
1029 i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
1031 return NT_STATUS_OK;
1034 /****************************************************************
1035 ****************************************************************/
1037 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1038 struct rpc_pipe_client *pipe_cli,
1039 struct dom_sid *domain_sid,
1040 struct policy_handle *domain_handle,
1041 struct policy_handle *builtin_handle,
1042 const char *user_name,
1046 uint32_t *num_entries)
1050 struct samr_UserInfo21 *info21 = NULL;
1051 struct sec_desc_buf *sec_desc = NULL;
1052 uint32_t auth_flag = 0;
1054 struct USER_INFO_0 info0;
1055 struct USER_INFO_1 info1;
1056 struct USER_INFO_2 info2;
1057 struct USER_INFO_3 info3;
1058 struct USER_INFO_4 info4;
1059 struct USER_INFO_10 info10;
1060 struct USER_INFO_11 info11;
1061 struct USER_INFO_20 info20;
1062 struct USER_INFO_23 info23;
1076 return NT_STATUS_INVALID_LEVEL;
1080 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1081 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1083 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1084 (struct USER_INFO_0 **)buffer, num_entries);
1086 return NT_STATUS_OK;
1089 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1100 if (!NT_STATUS_IS_OK(status)) {
1106 /* already returned above */
1109 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1110 NT_STATUS_NOT_OK_RETURN(status);
1112 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1113 (struct USER_INFO_1 **)buffer, num_entries);
1117 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1118 NT_STATUS_NOT_OK_RETURN(status);
1120 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1121 (struct USER_INFO_2 **)buffer, num_entries);
1125 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1126 NT_STATUS_NOT_OK_RETURN(status);
1128 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1129 (struct USER_INFO_3 **)buffer, num_entries);
1133 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1134 NT_STATUS_NOT_OK_RETURN(status);
1136 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1137 (struct USER_INFO_4 **)buffer, num_entries);
1141 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1142 NT_STATUS_NOT_OK_RETURN(status);
1144 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1145 (struct USER_INFO_10 **)buffer, num_entries);
1149 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1150 NT_STATUS_NOT_OK_RETURN(status);
1152 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1153 (struct USER_INFO_11 **)buffer, num_entries);
1157 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1158 NT_STATUS_NOT_OK_RETURN(status);
1160 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1161 (struct USER_INFO_20 **)buffer, num_entries);
1165 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1166 NT_STATUS_NOT_OK_RETURN(status);
1168 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1169 (struct USER_INFO_23 **)buffer, num_entries);
1172 return NT_STATUS_INVALID_LEVEL;
1179 /****************************************************************
1180 ****************************************************************/
1182 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1183 struct NetUserEnum *r)
1185 struct cli_state *cli = NULL;
1186 struct rpc_pipe_client *pipe_cli = NULL;
1187 struct policy_handle connect_handle;
1188 struct dom_sid2 *domain_sid = NULL;
1189 struct policy_handle domain_handle, builtin_handle;
1190 struct samr_SamArray *sam = NULL;
1191 uint32_t filter = ACB_NORMAL;
1193 uint32_t entries_read = 0;
1195 NTSTATUS status = NT_STATUS_OK;
1198 ZERO_STRUCT(connect_handle);
1199 ZERO_STRUCT(domain_handle);
1200 ZERO_STRUCT(builtin_handle);
1202 if (!r->out.buffer) {
1203 return WERR_INVALID_PARAM;
1206 *r->out.buffer = NULL;
1207 *r->out.entries_read = 0;
1209 switch (r->in.level) {
1221 return WERR_UNKNOWN_LEVEL;
1224 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1225 &ndr_table_samr.syntax_id,
1228 if (!W_ERROR_IS_OK(werr)) {
1232 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1233 SAMR_ACCESS_ENUM_DOMAINS |
1234 SAMR_ACCESS_OPEN_DOMAIN,
1235 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1236 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1239 if (!W_ERROR_IS_OK(werr)) {
1243 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1244 SAMR_ACCESS_ENUM_DOMAINS |
1245 SAMR_ACCESS_OPEN_DOMAIN,
1246 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1247 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1248 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1252 if (!W_ERROR_IS_OK(werr)) {
1256 switch (r->in.filter) {
1257 case FILTER_NORMAL_ACCOUNT:
1258 filter = ACB_NORMAL;
1260 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1261 filter = ACB_TEMPDUP;
1263 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1264 filter = ACB_DOMTRUST;
1266 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1267 filter = ACB_WSTRUST;
1269 case FILTER_SERVER_TRUST_ACCOUNT:
1270 filter = ACB_SVRTRUST;
1276 status = rpccli_samr_EnumDomainUsers(pipe_cli,
1279 r->in.resume_handle,
1284 werr = ntstatus_to_werror(status);
1285 if (NT_STATUS_IS_ERR(status)) {
1289 for (i=0; i < sam->count; i++) {
1291 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1295 sam->entries[i].name.string,
1296 sam->entries[i].idx,
1299 r->out.entries_read);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 werr = ntstatus_to_werror(status);
1312 if (NT_STATUS_IS_OK(status) ||
1313 NT_STATUS_IS_ERR(status)) {
1315 if (ctx->disable_policy_handle_cache) {
1316 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1317 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1318 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1325 /****************************************************************
1326 ****************************************************************/
1328 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1329 struct NetUserEnum *r)
1331 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1334 /****************************************************************
1335 ****************************************************************/
1337 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1338 struct samr_DispInfoGeneral *info,
1339 uint32_t *entries_read,
1342 struct NET_DISPLAY_USER *user = NULL;
1345 user = TALLOC_ZERO_ARRAY(mem_ctx,
1346 struct NET_DISPLAY_USER,
1348 W_ERROR_HAVE_NO_MEMORY(user);
1350 for (i = 0; i < info->count; i++) {
1351 user[i].usri1_name = talloc_strdup(mem_ctx,
1352 info->entries[i].account_name.string);
1353 user[i].usri1_comment = talloc_strdup(mem_ctx,
1354 info->entries[i].description.string);
1355 user[i].usri1_flags =
1356 info->entries[i].acct_flags;
1357 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1358 info->entries[i].full_name.string);
1359 user[i].usri1_user_id =
1360 info->entries[i].rid;
1361 user[i].usri1_next_index =
1362 info->entries[i].idx;
1364 if (!user[i].usri1_name) {
1369 *buffer = talloc_memdup(mem_ctx, user,
1370 sizeof(struct NET_DISPLAY_USER) * info->count);
1371 W_ERROR_HAVE_NO_MEMORY(*buffer);
1373 *entries_read = info->count;
1378 /****************************************************************
1379 ****************************************************************/
1381 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1382 struct samr_DispInfoFull *info,
1383 uint32_t *entries_read,
1386 struct NET_DISPLAY_MACHINE *machine = NULL;
1389 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1390 struct NET_DISPLAY_MACHINE,
1392 W_ERROR_HAVE_NO_MEMORY(machine);
1394 for (i = 0; i < info->count; i++) {
1395 machine[i].usri2_name = talloc_strdup(mem_ctx,
1396 info->entries[i].account_name.string);
1397 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1398 info->entries[i].description.string);
1399 machine[i].usri2_flags =
1400 info->entries[i].acct_flags;
1401 machine[i].usri2_user_id =
1402 info->entries[i].rid;
1403 machine[i].usri2_next_index =
1404 info->entries[i].idx;
1406 if (!machine[i].usri2_name) {
1411 *buffer = talloc_memdup(mem_ctx, machine,
1412 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1413 W_ERROR_HAVE_NO_MEMORY(*buffer);
1415 *entries_read = info->count;
1420 /****************************************************************
1421 ****************************************************************/
1423 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1424 struct samr_DispInfoFullGroups *info,
1425 uint32_t *entries_read,
1428 struct NET_DISPLAY_GROUP *group = NULL;
1431 group = TALLOC_ZERO_ARRAY(mem_ctx,
1432 struct NET_DISPLAY_GROUP,
1434 W_ERROR_HAVE_NO_MEMORY(group);
1436 for (i = 0; i < info->count; i++) {
1437 group[i].grpi3_name = talloc_strdup(mem_ctx,
1438 info->entries[i].account_name.string);
1439 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1440 info->entries[i].description.string);
1441 group[i].grpi3_group_id =
1442 info->entries[i].rid;
1443 group[i].grpi3_attributes =
1444 info->entries[i].acct_flags;
1445 group[i].grpi3_next_index =
1446 info->entries[i].idx;
1448 if (!group[i].grpi3_name) {
1453 *buffer = talloc_memdup(mem_ctx, group,
1454 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1455 W_ERROR_HAVE_NO_MEMORY(*buffer);
1457 *entries_read = info->count;
1463 /****************************************************************
1464 ****************************************************************/
1466 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1467 union samr_DispInfo *info,
1469 uint32_t *entries_read,
1474 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1479 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1484 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1489 return WERR_UNKNOWN_LEVEL;
1495 /****************************************************************
1496 ****************************************************************/
1498 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1499 struct NetQueryDisplayInformation *r)
1501 struct cli_state *cli = NULL;
1502 struct rpc_pipe_client *pipe_cli = NULL;
1503 struct policy_handle connect_handle;
1504 struct dom_sid2 *domain_sid = NULL;
1505 struct policy_handle domain_handle;
1506 union samr_DispInfo info;
1508 uint32_t total_size = 0;
1509 uint32_t returned_size = 0;
1511 NTSTATUS status = NT_STATUS_OK;
1514 ZERO_STRUCT(connect_handle);
1515 ZERO_STRUCT(domain_handle);
1517 switch (r->in.level) {
1523 return WERR_UNKNOWN_LEVEL;
1526 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1527 &ndr_table_samr.syntax_id,
1530 if (!W_ERROR_IS_OK(werr)) {
1534 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1535 SAMR_ACCESS_ENUM_DOMAINS |
1536 SAMR_ACCESS_OPEN_DOMAIN,
1537 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1538 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1539 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1543 if (!W_ERROR_IS_OK(werr)) {
1547 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1552 r->in.entries_requested,
1557 if (!NT_STATUS_IS_OK(status)) {
1558 werr = ntstatus_to_werror(status);
1562 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1564 r->out.entries_read,
1572 if (NT_STATUS_IS_OK(status) ||
1573 NT_STATUS_IS_ERR(status)) {
1575 if (ctx->disable_policy_handle_cache) {
1576 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1577 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1585 /****************************************************************
1586 ****************************************************************/
1589 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1590 struct NetQueryDisplayInformation *r)
1592 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1595 /****************************************************************
1596 ****************************************************************/
1598 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1599 struct NetUserChangePassword *r)
1601 return WERR_NOT_SUPPORTED;
1604 /****************************************************************
1605 ****************************************************************/
1607 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1608 struct NetUserChangePassword *r)
1610 return WERR_NOT_SUPPORTED;
1613 /****************************************************************
1614 ****************************************************************/
1616 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1617 struct NetUserGetInfo *r)
1619 struct cli_state *cli = NULL;
1620 struct rpc_pipe_client *pipe_cli = NULL;
1624 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1625 struct lsa_String lsa_account_name;
1626 struct dom_sid2 *domain_sid = NULL;
1627 struct samr_Ids user_rids, name_types;
1628 uint32_t num_entries = 0;
1630 ZERO_STRUCT(connect_handle);
1631 ZERO_STRUCT(domain_handle);
1632 ZERO_STRUCT(builtin_handle);
1633 ZERO_STRUCT(user_handle);
1635 if (!r->out.buffer) {
1636 return WERR_INVALID_PARAM;
1639 switch (r->in.level) {
1651 werr = WERR_UNKNOWN_LEVEL;
1655 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1656 &ndr_table_samr.syntax_id,
1659 if (!W_ERROR_IS_OK(werr)) {
1663 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1664 SAMR_ACCESS_ENUM_DOMAINS |
1665 SAMR_ACCESS_OPEN_DOMAIN,
1666 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1670 if (!W_ERROR_IS_OK(werr)) {
1674 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1675 SAMR_ACCESS_ENUM_DOMAINS |
1676 SAMR_ACCESS_OPEN_DOMAIN,
1677 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1678 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1681 if (!W_ERROR_IS_OK(werr)) {
1685 init_lsa_String(&lsa_account_name, r->in.user_name);
1687 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1693 if (!NT_STATUS_IS_OK(status)) {
1694 werr = ntstatus_to_werror(status);
1698 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1707 if (!NT_STATUS_IS_OK(status)) {
1708 werr = ntstatus_to_werror(status);
1717 if (is_valid_policy_hnd(&user_handle)) {
1718 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1721 if (ctx->disable_policy_handle_cache) {
1722 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1723 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1729 /****************************************************************
1730 ****************************************************************/
1732 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1733 struct NetUserGetInfo *r)
1735 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1738 /****************************************************************
1739 ****************************************************************/
1741 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1742 struct NetUserSetInfo *r)
1744 struct cli_state *cli = NULL;
1745 struct rpc_pipe_client *pipe_cli = NULL;
1749 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1750 struct lsa_String lsa_account_name;
1751 struct dom_sid2 *domain_sid = NULL;
1752 struct samr_Ids user_rids, name_types;
1753 uint32_t user_mask = 0;
1755 struct USER_INFO_X uX;
1757 ZERO_STRUCT(connect_handle);
1758 ZERO_STRUCT(domain_handle);
1759 ZERO_STRUCT(builtin_handle);
1760 ZERO_STRUCT(user_handle);
1762 if (!r->in.buffer) {
1763 return WERR_INVALID_PARAM;
1766 switch (r->in.level) {
1769 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1778 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1782 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1784 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1785 SAMR_USER_ACCESS_GET_GROUPS;
1788 user_mask = STD_RIGHT_READ_CONTROL_ACCESS |
1789 STD_RIGHT_WRITE_DAC_ACCESS |
1790 SAMR_USER_ACCESS_GET_GROUPS |
1791 SAMR_USER_ACCESS_SET_PASSWORD |
1792 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1793 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1794 SAMR_USER_ACCESS_SET_LOC_COM;
1806 werr = WERR_NOT_SUPPORTED;
1809 werr = WERR_UNKNOWN_LEVEL;
1813 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1814 &ndr_table_samr.syntax_id,
1817 if (!W_ERROR_IS_OK(werr)) {
1821 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1822 SAMR_ACCESS_ENUM_DOMAINS |
1823 SAMR_ACCESS_OPEN_DOMAIN,
1824 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1825 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1829 if (!W_ERROR_IS_OK(werr)) {
1833 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1834 SAMR_ACCESS_ENUM_DOMAINS |
1835 SAMR_ACCESS_OPEN_DOMAIN,
1836 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1837 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1840 if (!W_ERROR_IS_OK(werr)) {
1844 init_lsa_String(&lsa_account_name, r->in.user_name);
1846 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1852 if (!NT_STATUS_IS_OK(status)) {
1853 werr = ntstatus_to_werror(status);
1857 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1862 if (!NT_STATUS_IS_OK(status)) {
1863 werr = ntstatus_to_werror(status);
1867 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 werr = ntstatus_to_werror(status);
1873 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1874 &cli->user_session_key,
1877 if (!NT_STATUS_IS_OK(status)) {
1878 werr = ntstatus_to_werror(status);
1889 if (is_valid_policy_hnd(&user_handle)) {
1890 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1893 if (ctx->disable_policy_handle_cache) {
1894 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1895 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1896 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1902 /****************************************************************
1903 ****************************************************************/
1905 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1906 struct NetUserSetInfo *r)
1908 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1911 /****************************************************************
1912 ****************************************************************/
1914 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1915 struct rpc_pipe_client *pipe_cli,
1916 struct policy_handle *domain_handle,
1917 struct samr_DomInfo1 *info1,
1918 struct samr_DomInfo3 *info3,
1919 struct samr_DomInfo5 *info5,
1920 struct samr_DomInfo6 *info6,
1921 struct samr_DomInfo7 *info7,
1922 struct samr_DomInfo12 *info12)
1925 union samr_DomainInfo *dom_info = NULL;
1928 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1932 NT_STATUS_NOT_OK_RETURN(status);
1934 *info1 = dom_info->info1;
1938 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1942 NT_STATUS_NOT_OK_RETURN(status);
1944 *info3 = dom_info->info3;
1948 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1952 NT_STATUS_NOT_OK_RETURN(status);
1954 *info5 = dom_info->info5;
1958 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1962 NT_STATUS_NOT_OK_RETURN(status);
1964 *info6 = dom_info->info6;
1968 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1972 NT_STATUS_NOT_OK_RETURN(status);
1974 *info7 = dom_info->info7;
1978 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1982 NT_STATUS_NOT_OK_RETURN(status);
1984 *info12 = dom_info->info12;
1987 return NT_STATUS_OK;
1990 /****************************************************************
1991 ****************************************************************/
1993 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1994 struct rpc_pipe_client *pipe_cli,
1995 struct policy_handle *domain_handle,
1996 struct USER_MODALS_INFO_0 *info0)
1999 struct samr_DomInfo1 dom_info1;
2000 struct samr_DomInfo3 dom_info3;
2002 ZERO_STRUCTP(info0);
2004 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2013 NT_STATUS_NOT_OK_RETURN(status);
2015 info0->usrmod0_min_passwd_len =
2016 dom_info1.min_password_length;
2017 info0->usrmod0_max_passwd_age =
2018 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2019 info0->usrmod0_min_passwd_age =
2020 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2021 info0->usrmod0_password_hist_len =
2022 dom_info1.password_history_length;
2024 info0->usrmod0_force_logoff =
2025 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2027 return NT_STATUS_OK;
2030 /****************************************************************
2031 ****************************************************************/
2033 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2034 struct rpc_pipe_client *pipe_cli,
2035 struct policy_handle *domain_handle,
2036 struct USER_MODALS_INFO_1 *info1)
2039 struct samr_DomInfo6 dom_info6;
2040 struct samr_DomInfo7 dom_info7;
2042 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2051 NT_STATUS_NOT_OK_RETURN(status);
2053 info1->usrmod1_primary =
2054 talloc_strdup(mem_ctx, dom_info6.primary.string);
2056 info1->usrmod1_role = dom_info7.role;
2058 return NT_STATUS_OK;
2061 /****************************************************************
2062 ****************************************************************/
2064 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2065 struct rpc_pipe_client *pipe_cli,
2066 struct policy_handle *domain_handle,
2067 struct dom_sid *domain_sid,
2068 struct USER_MODALS_INFO_2 *info2)
2071 struct samr_DomInfo5 dom_info5;
2073 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2082 NT_STATUS_NOT_OK_RETURN(status);
2084 info2->usrmod2_domain_name =
2085 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2086 info2->usrmod2_domain_id =
2087 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
2089 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2090 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2092 return NT_STATUS_OK;
2095 /****************************************************************
2096 ****************************************************************/
2098 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2099 struct rpc_pipe_client *pipe_cli,
2100 struct policy_handle *domain_handle,
2101 struct USER_MODALS_INFO_3 *info3)
2104 struct samr_DomInfo12 dom_info12;
2106 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2115 NT_STATUS_NOT_OK_RETURN(status);
2117 info3->usrmod3_lockout_duration =
2118 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2119 info3->usrmod3_lockout_observation_window =
2120 nt_time_to_unix_abs(&dom_info12.lockout_window);
2121 info3->usrmod3_lockout_threshold =
2122 dom_info12.lockout_threshold;
2124 return NT_STATUS_OK;
2127 /****************************************************************
2128 ****************************************************************/
2130 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2131 struct rpc_pipe_client *pipe_cli,
2133 struct policy_handle *domain_handle,
2134 struct dom_sid *domain_sid,
2139 struct USER_MODALS_INFO_0 info0;
2140 struct USER_MODALS_INFO_1 info1;
2141 struct USER_MODALS_INFO_2 info2;
2142 struct USER_MODALS_INFO_3 info3;
2145 return ERROR_INSUFFICIENT_BUFFER;
2150 status = query_USER_MODALS_INFO_0(mem_ctx,
2154 NT_STATUS_NOT_OK_RETURN(status);
2156 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2161 status = query_USER_MODALS_INFO_1(mem_ctx,
2165 NT_STATUS_NOT_OK_RETURN(status);
2167 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2171 status = query_USER_MODALS_INFO_2(mem_ctx,
2176 NT_STATUS_NOT_OK_RETURN(status);
2178 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2182 status = query_USER_MODALS_INFO_3(mem_ctx,
2186 NT_STATUS_NOT_OK_RETURN(status);
2188 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2195 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2197 return NT_STATUS_OK;
2200 /****************************************************************
2201 ****************************************************************/
2203 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2204 struct NetUserModalsGet *r)
2206 struct cli_state *cli = NULL;
2207 struct rpc_pipe_client *pipe_cli = NULL;
2211 struct policy_handle connect_handle, domain_handle;
2212 struct dom_sid2 *domain_sid = NULL;
2213 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2215 ZERO_STRUCT(connect_handle);
2216 ZERO_STRUCT(domain_handle);
2218 if (!r->out.buffer) {
2219 return WERR_INVALID_PARAM;
2222 switch (r->in.level) {
2224 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2225 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2229 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2232 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2235 werr = WERR_UNKNOWN_LEVEL;
2239 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2240 &ndr_table_samr.syntax_id,
2243 if (!W_ERROR_IS_OK(werr)) {
2247 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2248 SAMR_ACCESS_ENUM_DOMAINS |
2249 SAMR_ACCESS_OPEN_DOMAIN,
2254 if (!W_ERROR_IS_OK(werr)) {
2261 /* 3: 12 (DomainInfo2) */
2263 status = query_USER_MODALS_INFO_to_buffer(ctx,
2269 if (!NT_STATUS_IS_OK(status)) {
2270 werr = ntstatus_to_werror(status);
2279 if (ctx->disable_policy_handle_cache) {
2280 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2281 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2287 /****************************************************************
2288 ****************************************************************/
2290 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2291 struct NetUserModalsGet *r)
2293 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2296 /****************************************************************
2297 ****************************************************************/
2299 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2300 struct rpc_pipe_client *pipe_cli,
2301 struct policy_handle *domain_handle,
2302 struct samr_DomInfo1 *info1,
2303 struct samr_DomInfo3 *info3,
2304 struct samr_DomInfo12 *info12)
2307 union samr_DomainInfo dom_info;
2311 ZERO_STRUCT(dom_info);
2313 dom_info.info1 = *info1;
2315 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2319 NT_STATUS_NOT_OK_RETURN(status);
2324 ZERO_STRUCT(dom_info);
2326 dom_info.info3 = *info3;
2328 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2333 NT_STATUS_NOT_OK_RETURN(status);
2338 ZERO_STRUCT(dom_info);
2340 dom_info.info12 = *info12;
2342 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2347 NT_STATUS_NOT_OK_RETURN(status);
2350 return NT_STATUS_OK;
2353 /****************************************************************
2354 ****************************************************************/
2356 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2357 struct rpc_pipe_client *pipe_cli,
2358 struct policy_handle *domain_handle,
2359 struct USER_MODALS_INFO_0 *info0)
2362 struct samr_DomInfo1 dom_info_1;
2363 struct samr_DomInfo3 dom_info_3;
2365 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2374 NT_STATUS_NOT_OK_RETURN(status);
2376 dom_info_1.min_password_length =
2377 info0->usrmod0_min_passwd_len;
2378 dom_info_1.password_history_length =
2379 info0->usrmod0_password_hist_len;
2381 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2382 info0->usrmod0_max_passwd_age);
2383 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2384 info0->usrmod0_min_passwd_age);
2386 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2387 info0->usrmod0_force_logoff);
2389 return set_USER_MODALS_INFO_rpc(mem_ctx,
2397 /****************************************************************
2398 ****************************************************************/
2400 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2401 struct rpc_pipe_client *pipe_cli,
2402 struct policy_handle *domain_handle,
2403 struct USER_MODALS_INFO_3 *info3)
2406 struct samr_DomInfo12 dom_info_12;
2408 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2417 NT_STATUS_NOT_OK_RETURN(status);
2419 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2420 info3->usrmod3_lockout_duration);
2421 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2422 info3->usrmod3_lockout_observation_window);
2423 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2425 return set_USER_MODALS_INFO_rpc(mem_ctx,
2433 /****************************************************************
2434 ****************************************************************/
2436 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2437 struct rpc_pipe_client *pipe_cli,
2438 struct policy_handle *domain_handle,
2439 struct USER_MODALS_INFO_1001 *info1001)
2442 struct samr_DomInfo1 dom_info_1;
2444 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2453 NT_STATUS_NOT_OK_RETURN(status);
2455 dom_info_1.min_password_length =
2456 info1001->usrmod1001_min_passwd_len;
2458 return set_USER_MODALS_INFO_rpc(mem_ctx,
2466 /****************************************************************
2467 ****************************************************************/
2469 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2470 struct rpc_pipe_client *pipe_cli,
2471 struct policy_handle *domain_handle,
2472 struct USER_MODALS_INFO_1002 *info1002)
2475 struct samr_DomInfo1 dom_info_1;
2477 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2486 NT_STATUS_NOT_OK_RETURN(status);
2488 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2489 info1002->usrmod1002_max_passwd_age);
2491 return set_USER_MODALS_INFO_rpc(mem_ctx,
2499 /****************************************************************
2500 ****************************************************************/
2502 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2503 struct rpc_pipe_client *pipe_cli,
2504 struct policy_handle *domain_handle,
2505 struct USER_MODALS_INFO_1003 *info1003)
2508 struct samr_DomInfo1 dom_info_1;
2510 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2519 NT_STATUS_NOT_OK_RETURN(status);
2521 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2522 info1003->usrmod1003_min_passwd_age);
2524 return set_USER_MODALS_INFO_rpc(mem_ctx,
2532 /****************************************************************
2533 ****************************************************************/
2535 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2536 struct rpc_pipe_client *pipe_cli,
2537 struct policy_handle *domain_handle,
2538 struct USER_MODALS_INFO_1004 *info1004)
2541 struct samr_DomInfo3 dom_info_3;
2543 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2552 NT_STATUS_NOT_OK_RETURN(status);
2554 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2555 info1004->usrmod1004_force_logoff);
2557 return set_USER_MODALS_INFO_rpc(mem_ctx,
2565 /****************************************************************
2566 ****************************************************************/
2568 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2569 struct rpc_pipe_client *pipe_cli,
2570 struct policy_handle *domain_handle,
2571 struct USER_MODALS_INFO_1005 *info1005)
2574 struct samr_DomInfo1 dom_info_1;
2576 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2585 NT_STATUS_NOT_OK_RETURN(status);
2587 dom_info_1.password_history_length =
2588 info1005->usrmod1005_password_hist_len;
2590 return set_USER_MODALS_INFO_rpc(mem_ctx,
2598 /****************************************************************
2599 ****************************************************************/
2601 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2602 struct rpc_pipe_client *pipe_cli,
2604 struct policy_handle *domain_handle,
2605 struct dom_sid *domain_sid,
2608 struct USER_MODALS_INFO_0 *info0;
2609 struct USER_MODALS_INFO_3 *info3;
2610 struct USER_MODALS_INFO_1001 *info1001;
2611 struct USER_MODALS_INFO_1002 *info1002;
2612 struct USER_MODALS_INFO_1003 *info1003;
2613 struct USER_MODALS_INFO_1004 *info1004;
2614 struct USER_MODALS_INFO_1005 *info1005;
2617 return ERROR_INSUFFICIENT_BUFFER;
2622 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2623 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2628 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2629 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2634 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2635 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2640 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2641 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2646 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2647 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2652 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2653 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2658 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2659 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2668 return NT_STATUS_OK;
2671 /****************************************************************
2672 ****************************************************************/
2674 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2675 struct NetUserModalsSet *r)
2677 struct cli_state *cli = NULL;
2678 struct rpc_pipe_client *pipe_cli = NULL;
2682 struct policy_handle connect_handle, domain_handle;
2683 struct dom_sid2 *domain_sid = NULL;
2684 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2686 ZERO_STRUCT(connect_handle);
2687 ZERO_STRUCT(domain_handle);
2689 if (!r->in.buffer) {
2690 return WERR_INVALID_PARAM;
2693 switch (r->in.level) {
2695 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2696 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2697 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2698 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2705 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2706 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2709 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2710 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2716 werr = WERR_NOT_SUPPORTED;
2719 werr = WERR_UNKNOWN_LEVEL;
2723 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2724 &ndr_table_samr.syntax_id,
2727 if (!W_ERROR_IS_OK(werr)) {
2731 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2732 SAMR_ACCESS_ENUM_DOMAINS |
2733 SAMR_ACCESS_OPEN_DOMAIN,
2738 if (!W_ERROR_IS_OK(werr)) {
2742 status = set_USER_MODALS_INFO_buffer(ctx,
2748 if (!NT_STATUS_IS_OK(status)) {
2749 werr = ntstatus_to_werror(status);
2758 if (ctx->disable_policy_handle_cache) {
2759 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2760 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2766 /****************************************************************
2767 ****************************************************************/
2769 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2770 struct NetUserModalsSet *r)
2772 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2775 /****************************************************************
2776 ****************************************************************/
2778 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2780 const char *group_name,
2781 uint32_t attributes,
2783 uint32_t *num_entries)
2785 struct GROUP_USERS_INFO_0 u0;
2786 struct GROUP_USERS_INFO_1 u1;
2790 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2791 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2793 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2794 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2797 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2798 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2800 u1.grui1_attributes = attributes;
2802 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2803 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2806 return NT_STATUS_INVALID_INFO_CLASS;
2809 return NT_STATUS_OK;
2812 /****************************************************************
2813 ****************************************************************/
2815 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2816 struct NetUserGetGroups *r)
2818 struct cli_state *cli = NULL;
2819 struct rpc_pipe_client *pipe_cli = NULL;
2820 struct policy_handle connect_handle, domain_handle, user_handle;
2821 struct lsa_String lsa_account_name;
2822 struct dom_sid2 *domain_sid = NULL;
2823 struct samr_Ids user_rids, name_types;
2824 struct samr_RidWithAttributeArray *rid_array = NULL;
2825 struct lsa_Strings names;
2826 struct samr_Ids types;
2827 uint32_t *rids = NULL;
2830 uint32_t entries_read = 0;
2832 NTSTATUS status = NT_STATUS_OK;
2835 ZERO_STRUCT(connect_handle);
2836 ZERO_STRUCT(domain_handle);
2838 if (!r->out.buffer) {
2839 return WERR_INVALID_PARAM;
2842 *r->out.buffer = NULL;
2843 *r->out.entries_read = 0;
2845 switch (r->in.level) {
2850 return WERR_UNKNOWN_LEVEL;
2853 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2854 &ndr_table_samr.syntax_id,
2857 if (!W_ERROR_IS_OK(werr)) {
2861 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2862 SAMR_ACCESS_ENUM_DOMAINS |
2863 SAMR_ACCESS_OPEN_DOMAIN,
2864 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2868 if (!W_ERROR_IS_OK(werr)) {
2872 init_lsa_String(&lsa_account_name, r->in.user_name);
2874 status = rpccli_samr_LookupNames(pipe_cli, ctx,
2880 if (!NT_STATUS_IS_OK(status)) {
2881 werr = ntstatus_to_werror(status);
2885 status = rpccli_samr_OpenUser(pipe_cli, ctx,
2887 SAMR_USER_ACCESS_GET_GROUPS,
2890 if (!NT_STATUS_IS_OK(status)) {
2891 werr = ntstatus_to_werror(status);
2895 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2898 if (!NT_STATUS_IS_OK(status)) {
2899 werr = ntstatus_to_werror(status);
2903 rids = talloc_array(ctx, uint32_t, rid_array->count);
2909 for (i=0; i < rid_array->count; i++) {
2910 rids[i] = rid_array->rids[i].rid;
2913 status = rpccli_samr_LookupRids(pipe_cli, ctx,
2919 if (!NT_STATUS_IS_OK(status)) {
2920 werr = ntstatus_to_werror(status);
2924 for (i=0; i < rid_array->count; i++) {
2925 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2927 names.names[i].string,
2928 rid_array->rids[i].attributes,
2931 if (!NT_STATUS_IS_OK(status)) {
2932 werr = ntstatus_to_werror(status);
2937 if (r->out.entries_read) {
2938 *r->out.entries_read = entries_read;
2940 if (r->out.total_entries) {
2941 *r->out.total_entries = entries_read;
2949 if (ctx->disable_policy_handle_cache) {
2950 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2951 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2957 /****************************************************************
2958 ****************************************************************/
2960 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2961 struct NetUserGetGroups *r)
2963 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
2966 /****************************************************************
2967 ****************************************************************/
2969 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
2970 struct NetUserSetGroups *r)
2972 struct cli_state *cli = NULL;
2973 struct rpc_pipe_client *pipe_cli = NULL;
2974 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
2975 struct lsa_String lsa_account_name;
2976 struct dom_sid2 *domain_sid = NULL;
2977 struct samr_Ids user_rids, name_types;
2978 struct samr_Ids group_rids;
2979 struct samr_RidWithAttributeArray *rid_array = NULL;
2980 struct lsa_String *lsa_names = NULL;
2982 uint32_t *add_rids = NULL;
2983 uint32_t *del_rids = NULL;
2984 size_t num_add_rids = 0;
2985 size_t num_del_rids = 0;
2987 uint32_t *member_rids = NULL;
2988 size_t num_member_rids = 0;
2990 struct GROUP_USERS_INFO_0 *i0 = NULL;
2991 struct GROUP_USERS_INFO_1 *i1 = NULL;
2995 NTSTATUS status = NT_STATUS_OK;
2998 ZERO_STRUCT(connect_handle);
2999 ZERO_STRUCT(domain_handle);
3001 if (!r->in.buffer) {
3002 return WERR_INVALID_PARAM;
3005 switch (r->in.level) {
3010 return WERR_UNKNOWN_LEVEL;
3013 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3014 &ndr_table_samr.syntax_id,
3017 if (!W_ERROR_IS_OK(werr)) {
3021 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3022 SAMR_ACCESS_ENUM_DOMAINS |
3023 SAMR_ACCESS_OPEN_DOMAIN,
3024 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3028 if (!W_ERROR_IS_OK(werr)) {
3032 init_lsa_String(&lsa_account_name, r->in.user_name);
3034 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3040 if (!NT_STATUS_IS_OK(status)) {
3041 werr = ntstatus_to_werror(status);
3045 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3047 SAMR_USER_ACCESS_GET_GROUPS,
3050 if (!NT_STATUS_IS_OK(status)) {
3051 werr = ntstatus_to_werror(status);
3055 switch (r->in.level) {
3057 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3060 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3064 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3070 for (i=0; i < r->in.num_entries; i++) {
3072 switch (r->in.level) {
3074 init_lsa_String(&lsa_names[i], i0->grui0_name);
3078 init_lsa_String(&lsa_names[i], i1->grui1_name);
3084 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3090 if (!NT_STATUS_IS_OK(status)) {
3091 werr = ntstatus_to_werror(status);
3095 member_rids = group_rids.ids;
3096 num_member_rids = group_rids.count;
3098 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3101 if (!NT_STATUS_IS_OK(status)) {
3102 werr = ntstatus_to_werror(status);
3108 for (i=0; i < r->in.num_entries; i++) {
3109 bool already_member = false;
3110 for (k=0; k < rid_array->count; k++) {
3111 if (member_rids[i] == rid_array->rids[k].rid) {
3112 already_member = true;
3116 if (!already_member) {
3117 if (!add_rid_to_array_unique(ctx,
3119 &add_rids, &num_add_rids)) {
3120 werr = WERR_GENERAL_FAILURE;
3128 for (k=0; k < rid_array->count; k++) {
3129 bool keep_member = false;
3130 for (i=0; i < r->in.num_entries; i++) {
3131 if (member_rids[i] == rid_array->rids[k].rid) {
3137 if (!add_rid_to_array_unique(ctx,
3138 rid_array->rids[k].rid,
3139 &del_rids, &num_del_rids)) {
3140 werr = WERR_GENERAL_FAILURE;
3148 for (i=0; i < num_add_rids; i++) {
3149 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3151 SAMR_GROUP_ACCESS_ADD_MEMBER,
3154 if (!NT_STATUS_IS_OK(status)) {
3155 werr = ntstatus_to_werror(status);
3159 status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
3163 if (!NT_STATUS_IS_OK(status)) {
3164 werr = ntstatus_to_werror(status);
3168 if (is_valid_policy_hnd(&group_handle)) {
3169 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3175 for (i=0; i < num_del_rids; i++) {
3176 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3178 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3181 if (!NT_STATUS_IS_OK(status)) {
3182 werr = ntstatus_to_werror(status);
3186 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
3189 if (!NT_STATUS_IS_OK(status)) {
3190 werr = ntstatus_to_werror(status);
3194 if (is_valid_policy_hnd(&group_handle)) {
3195 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3206 if (is_valid_policy_hnd(&group_handle)) {
3207 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3210 if (ctx->disable_policy_handle_cache) {
3211 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3212 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3218 /****************************************************************
3219 ****************************************************************/
3221 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3222 struct NetUserSetGroups *r)
3224 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3227 /****************************************************************
3228 ****************************************************************/
3230 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3232 const char *group_name,
3234 uint32_t *num_entries)
3236 struct LOCALGROUP_USERS_INFO_0 u0;
3240 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3241 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3243 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3244 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3247 return NT_STATUS_INVALID_INFO_CLASS;
3250 return NT_STATUS_OK;
3253 /****************************************************************
3254 ****************************************************************/
3256 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3257 struct NetUserGetLocalGroups *r)
3259 struct cli_state *cli = NULL;
3260 struct rpc_pipe_client *pipe_cli = NULL;
3261 struct policy_handle connect_handle, domain_handle, user_handle,
3263 struct lsa_String lsa_account_name;
3264 struct dom_sid2 *domain_sid = NULL;
3265 struct samr_Ids user_rids, name_types;
3266 struct samr_RidWithAttributeArray *rid_array = NULL;
3267 struct lsa_Strings names;
3268 struct samr_Ids types;
3269 uint32_t *rids = NULL;
3270 size_t num_rids = 0;
3271 struct dom_sid user_sid;
3272 struct lsa_SidArray sid_array;
3273 struct samr_Ids domain_rids;
3274 struct samr_Ids builtin_rids;
3277 uint32_t entries_read = 0;
3279 NTSTATUS status = NT_STATUS_OK;
3282 ZERO_STRUCT(connect_handle);
3283 ZERO_STRUCT(domain_handle);
3285 if (!r->out.buffer) {
3286 return WERR_INVALID_PARAM;
3289 *r->out.buffer = NULL;
3290 *r->out.entries_read = 0;
3292 switch (r->in.level) {
3297 return WERR_UNKNOWN_LEVEL;
3300 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3301 &ndr_table_samr.syntax_id,
3304 if (!W_ERROR_IS_OK(werr)) {
3308 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3309 SAMR_ACCESS_ENUM_DOMAINS |
3310 SAMR_ACCESS_OPEN_DOMAIN,
3311 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3312 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3316 if (!W_ERROR_IS_OK(werr)) {
3320 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3321 SAMR_ACCESS_ENUM_DOMAINS |
3322 SAMR_ACCESS_OPEN_DOMAIN,
3323 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3324 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3327 if (!W_ERROR_IS_OK(werr)) {
3331 init_lsa_String(&lsa_account_name, r->in.user_name);
3333 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3339 if (!NT_STATUS_IS_OK(status)) {
3340 werr = ntstatus_to_werror(status);
3344 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3346 SAMR_USER_ACCESS_GET_GROUPS,
3349 if (!NT_STATUS_IS_OK(status)) {
3350 werr = ntstatus_to_werror(status);
3354 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3357 if (!NT_STATUS_IS_OK(status)) {
3358 werr = ntstatus_to_werror(status);
3362 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3367 sid_array.num_sids = rid_array->count + 1;
3368 sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
3369 if (!sid_array.sids) {
3374 sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid);
3375 if (!sid_array.sids[0].sid) {
3380 for (i=0; i < rid_array->count; i++) {
3383 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3388 sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid);
3389 if (!sid_array.sids[i+1].sid) {
3395 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3399 if (!NT_STATUS_IS_OK(status)) {
3400 werr = ntstatus_to_werror(status);
3404 for (i=0; i < domain_rids.count; i++) {
3405 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3406 &rids, &num_rids)) {
3412 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3416 if (!NT_STATUS_IS_OK(status)) {
3417 werr = ntstatus_to_werror(status);
3421 for (i=0; i < builtin_rids.count; i++) {
3422 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3423 &rids, &num_rids)) {
3429 status = rpccli_samr_LookupRids(pipe_cli, ctx,
3435 if (!NT_STATUS_IS_OK(status)) {
3436 werr = ntstatus_to_werror(status);
3440 for (i=0; i < names.count; i++) {
3441 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3443 names.names[i].string,
3446 if (!NT_STATUS_IS_OK(status)) {
3447 werr = ntstatus_to_werror(status);
3452 if (r->out.entries_read) {
3453 *r->out.entries_read = entries_read;
3455 if (r->out.total_entries) {
3456 *r->out.total_entries = entries_read;
3464 if (ctx->disable_policy_handle_cache) {
3465 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3466 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3472 /****************************************************************
3473 ****************************************************************/
3475 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3476 struct NetUserGetLocalGroups *r)
3478 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);