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"
26 #include "../librpc/gen_ndr/ndr_samr_c.h"
27 #include "rpc_client/init_samr.h"
28 #include "../libds/common/flags.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../libds/common/flag_mapping.h"
32 #include "rpc_client/cli_pipe.h"
34 /****************************************************************
35 ****************************************************************/
37 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
38 struct samr_UserInfo21 *info21)
40 uint32_t fields_present = 0;
41 struct samr_LogonHours zero_logon_hours;
42 struct lsa_BinaryString zero_parameters;
46 ZERO_STRUCT(zero_logon_hours);
47 ZERO_STRUCT(zero_parameters);
49 if (infoX->usriX_flags) {
50 fields_present |= SAMR_FIELD_ACCT_FLAGS;
52 if (infoX->usriX_name) {
53 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
55 if (infoX->usriX_password) {
56 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
58 if (infoX->usriX_flags) {
59 fields_present |= SAMR_FIELD_ACCT_FLAGS;
61 if (infoX->usriX_home_dir) {
62 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
64 if (infoX->usriX_script_path) {
65 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
67 if (infoX->usriX_comment) {
68 fields_present |= SAMR_FIELD_DESCRIPTION;
70 if (infoX->usriX_password_age) {
71 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
73 if (infoX->usriX_full_name) {
74 fields_present |= SAMR_FIELD_FULL_NAME;
76 if (infoX->usriX_usr_comment) {
77 fields_present |= SAMR_FIELD_COMMENT;
79 if (infoX->usriX_profile) {
80 fields_present |= SAMR_FIELD_PROFILE_PATH;
82 if (infoX->usriX_home_dir_drive) {
83 fields_present |= SAMR_FIELD_HOME_DRIVE;
85 if (infoX->usriX_primary_group_id) {
86 fields_present |= SAMR_FIELD_PRIMARY_GID;
88 if (infoX->usriX_country_code) {
89 fields_present |= SAMR_FIELD_COUNTRY_CODE;
91 if (infoX->usriX_workstations) {
92 fields_present |= SAMR_FIELD_WORKSTATIONS;
95 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
97 /* TODO: infoX->usriX_priv */
99 info21->last_logon = 0;
100 info21->last_logoff = 0;
101 info21->last_password_change = 0;
102 info21->acct_expiry = 0;
103 info21->allow_password_change = 0;
104 info21->force_password_change = 0;
105 info21->account_name.string = infoX->usriX_name;
106 info21->full_name.string = infoX->usriX_full_name;
107 info21->home_directory.string = infoX->usriX_home_dir;
108 info21->home_drive.string = infoX->usriX_home_dir_drive;
109 info21->logon_script.string = infoX->usriX_script_path;
110 info21->profile_path.string = infoX->usriX_profile;
111 info21->description.string = infoX->usriX_comment;
112 info21->workstations.string = infoX->usriX_workstations;
113 info21->comment.string = infoX->usriX_usr_comment;
114 info21->parameters = zero_parameters;
115 info21->lm_owf_password = zero_parameters;
116 info21->nt_owf_password = zero_parameters;
117 info21->private_data.string = NULL;
118 info21->buf_count = 0;
119 info21->buffer = NULL;
120 info21->rid = infoX->usriX_user_id;
121 info21->primary_gid = infoX->usriX_primary_group_id;
122 info21->acct_flags = infoX->usriX_flags;
123 info21->fields_present = fields_present;
124 info21->logon_hours = zero_logon_hours;
125 info21->bad_password_count = infoX->usriX_bad_pw_count;
126 info21->logon_count = infoX->usriX_num_logons;
127 info21->country_code = infoX->usriX_country_code;
128 info21->code_page = infoX->usriX_code_page;
129 info21->lm_password_set = 0;
130 info21->nt_password_set = 0;
131 info21->password_expired = infoX->usriX_password_expired;
132 info21->private_data_sensitive = 0;
135 /****************************************************************
136 ****************************************************************/
138 static NTSTATUS construct_USER_INFO_X(uint32_t level,
140 struct USER_INFO_X *uX)
142 struct USER_INFO_0 *u0 = NULL;
143 struct USER_INFO_1 *u1 = NULL;
144 struct USER_INFO_2 *u2 = NULL;
145 struct USER_INFO_3 *u3 = NULL;
146 struct USER_INFO_1003 *u1003 = NULL;
147 struct USER_INFO_1006 *u1006 = NULL;
148 struct USER_INFO_1007 *u1007 = NULL;
149 struct USER_INFO_1009 *u1009 = NULL;
150 struct USER_INFO_1011 *u1011 = NULL;
151 struct USER_INFO_1012 *u1012 = NULL;
152 struct USER_INFO_1014 *u1014 = NULL;
153 struct USER_INFO_1024 *u1024 = NULL;
154 struct USER_INFO_1051 *u1051 = NULL;
155 struct USER_INFO_1052 *u1052 = NULL;
156 struct USER_INFO_1053 *u1053 = NULL;
158 if (!buffer || !uX) {
159 return NT_STATUS_INVALID_PARAMETER;
166 u0 = (struct USER_INFO_0 *)buffer;
167 uX->usriX_name = u0->usri0_name;
170 u1 = (struct USER_INFO_1 *)buffer;
171 uX->usriX_name = u1->usri1_name;
172 uX->usriX_password = u1->usri1_password;
173 uX->usriX_password_age = u1->usri1_password_age;
174 uX->usriX_priv = u1->usri1_priv;
175 uX->usriX_home_dir = u1->usri1_home_dir;
176 uX->usriX_comment = u1->usri1_comment;
177 uX->usriX_flags = u1->usri1_flags;
178 uX->usriX_script_path = u1->usri1_script_path;
181 u2 = (struct USER_INFO_2 *)buffer;
182 uX->usriX_name = u2->usri2_name;
183 uX->usriX_password = u2->usri2_password;
184 uX->usriX_password_age = u2->usri2_password_age;
185 uX->usriX_priv = u2->usri2_priv;
186 uX->usriX_home_dir = u2->usri2_home_dir;
187 uX->usriX_comment = u2->usri2_comment;
188 uX->usriX_flags = u2->usri2_flags;
189 uX->usriX_script_path = u2->usri2_script_path;
190 uX->usriX_auth_flags = u2->usri2_auth_flags;
191 uX->usriX_full_name = u2->usri2_full_name;
192 uX->usriX_usr_comment = u2->usri2_usr_comment;
193 uX->usriX_parms = u2->usri2_parms;
194 uX->usriX_workstations = u2->usri2_workstations;
195 uX->usriX_last_logon = u2->usri2_last_logon;
196 uX->usriX_last_logoff = u2->usri2_last_logoff;
197 uX->usriX_acct_expires = u2->usri2_acct_expires;
198 uX->usriX_max_storage = u2->usri2_max_storage;
199 uX->usriX_units_per_week= u2->usri2_units_per_week;
200 uX->usriX_logon_hours = u2->usri2_logon_hours;
201 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
202 uX->usriX_num_logons = u2->usri2_num_logons;
203 uX->usriX_logon_server = u2->usri2_logon_server;
204 uX->usriX_country_code = u2->usri2_country_code;
205 uX->usriX_code_page = u2->usri2_code_page;
208 u3 = (struct USER_INFO_3 *)buffer;
209 uX->usriX_name = u3->usri3_name;
210 uX->usriX_password_age = u3->usri3_password_age;
211 uX->usriX_priv = u3->usri3_priv;
212 uX->usriX_home_dir = u3->usri3_home_dir;
213 uX->usriX_comment = u3->usri3_comment;
214 uX->usriX_flags = u3->usri3_flags;
215 uX->usriX_script_path = u3->usri3_script_path;
216 uX->usriX_auth_flags = u3->usri3_auth_flags;
217 uX->usriX_full_name = u3->usri3_full_name;
218 uX->usriX_usr_comment = u3->usri3_usr_comment;
219 uX->usriX_parms = u3->usri3_parms;
220 uX->usriX_workstations = u3->usri3_workstations;
221 uX->usriX_last_logon = u3->usri3_last_logon;
222 uX->usriX_last_logoff = u3->usri3_last_logoff;
223 uX->usriX_acct_expires = u3->usri3_acct_expires;
224 uX->usriX_max_storage = u3->usri3_max_storage;
225 uX->usriX_units_per_week= u3->usri3_units_per_week;
226 uX->usriX_logon_hours = u3->usri3_logon_hours;
227 uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
228 uX->usriX_num_logons = u3->usri3_num_logons;
229 uX->usriX_logon_server = u3->usri3_logon_server;
230 uX->usriX_country_code = u3->usri3_country_code;
231 uX->usriX_code_page = u3->usri3_code_page;
232 uX->usriX_user_id = u3->usri3_user_id;
233 uX->usriX_primary_group_id = u3->usri3_primary_group_id;
234 uX->usriX_profile = u3->usri3_profile;
235 uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
236 uX->usriX_password_expired = u3->usri3_password_expired;
239 u1003 = (struct USER_INFO_1003 *)buffer;
240 uX->usriX_password = u1003->usri1003_password;
243 u1006 = (struct USER_INFO_1006 *)buffer;
244 uX->usriX_home_dir = u1006->usri1006_home_dir;
247 u1007 = (struct USER_INFO_1007 *)buffer;
248 uX->usriX_comment = u1007->usri1007_comment;
251 u1009 = (struct USER_INFO_1009 *)buffer;
252 uX->usriX_script_path = u1009->usri1009_script_path;
255 u1011 = (struct USER_INFO_1011 *)buffer;
256 uX->usriX_full_name = u1011->usri1011_full_name;
259 u1012 = (struct USER_INFO_1012 *)buffer;
260 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
263 u1014 = (struct USER_INFO_1014 *)buffer;
264 uX->usriX_workstations = u1014->usri1014_workstations;
267 u1024 = (struct USER_INFO_1024 *)buffer;
268 uX->usriX_country_code = u1024->usri1024_country_code;
271 u1051 = (struct USER_INFO_1051 *)buffer;
272 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
275 u1052 = (struct USER_INFO_1052 *)buffer;
276 uX->usriX_profile = u1052->usri1052_profile;
279 u1053 = (struct USER_INFO_1053 *)buffer;
280 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
284 return NT_STATUS_INVALID_INFO_CLASS;
290 /****************************************************************
291 ****************************************************************/
293 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
294 struct rpc_pipe_client *pipe_cli,
295 DATA_BLOB *session_key,
296 struct policy_handle *user_handle,
297 struct USER_INFO_X *uX)
299 union samr_UserInfo user_info;
300 struct samr_UserInfo21 info21;
301 NTSTATUS status, result;
302 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
305 return NT_STATUS_INVALID_PARAMETER;
308 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
310 ZERO_STRUCT(user_info);
312 if (uX->usriX_password) {
314 user_info.info25.info = info21;
316 init_samr_CryptPasswordEx(uX->usriX_password,
318 &user_info.info25.password);
320 status = dcerpc_samr_SetUserInfo2(b, talloc_tos(),
325 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
327 user_info.info23.info = info21;
329 init_samr_CryptPassword(uX->usriX_password,
331 &user_info.info23.password);
333 status = dcerpc_samr_SetUserInfo2(b, talloc_tos(),
338 if (!NT_STATUS_IS_OK(status)) {
343 if (!NT_STATUS_IS_OK(status)) {
348 user_info.info21 = info21;
350 status = dcerpc_samr_SetUserInfo(b, talloc_tos(),
355 if (!NT_STATUS_IS_OK(status)) {
363 /****************************************************************
364 ****************************************************************/
366 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
367 struct NetUserAdd *r)
369 struct rpc_pipe_client *pipe_cli = NULL;
370 NTSTATUS status, result;
372 struct policy_handle connect_handle, domain_handle, user_handle;
373 struct lsa_String lsa_account_name;
374 struct dom_sid2 *domain_sid = NULL;
375 union samr_UserInfo *user_info = NULL;
376 struct samr_PwInfo pw_info;
377 uint32_t access_granted = 0;
379 struct USER_INFO_X uX;
380 struct dcerpc_binding_handle *b = NULL;
381 DATA_BLOB session_key;
383 ZERO_STRUCT(connect_handle);
384 ZERO_STRUCT(domain_handle);
385 ZERO_STRUCT(user_handle);
388 return WERR_INVALID_PARAM;
391 switch (r->in.level) {
398 werr = WERR_NOT_SUPPORTED;
402 werr = libnetapi_open_pipe(ctx, r->in.server_name,
405 if (!W_ERROR_IS_OK(werr)) {
409 b = pipe_cli->binding_handle;
411 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
412 if (!NT_STATUS_IS_OK(status)) {
413 werr = ntstatus_to_werror(status);
417 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
418 SAMR_ACCESS_ENUM_DOMAINS |
419 SAMR_ACCESS_LOOKUP_DOMAIN,
420 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
421 SAMR_DOMAIN_ACCESS_CREATE_USER |
422 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
426 if (!W_ERROR_IS_OK(werr)) {
430 init_lsa_String(&lsa_account_name, uX.usriX_name);
432 status = dcerpc_samr_CreateUser2(b, talloc_tos(),
438 SAMR_USER_ACCESS_SET_PASSWORD |
439 SAMR_USER_ACCESS_SET_ATTRIBUTES |
440 SAMR_USER_ACCESS_GET_ATTRIBUTES,
445 if (!NT_STATUS_IS_OK(status)) {
446 werr = ntstatus_to_werror(status);
449 if (!NT_STATUS_IS_OK(result)) {
450 werr = ntstatus_to_werror(result);
454 status = dcerpc_samr_QueryUserInfo(b, talloc_tos(),
459 if (!NT_STATUS_IS_OK(status)) {
460 werr = ntstatus_to_werror(status);
463 if (!NT_STATUS_IS_OK(result)) {
464 werr = ntstatus_to_werror(result);
468 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
469 werr = WERR_INVALID_PARAM;
473 status = dcerpc_samr_GetUserPwInfo(b, talloc_tos(),
477 if (!NT_STATUS_IS_OK(status)) {
478 werr = ntstatus_to_werror(status);
481 if (!NT_STATUS_IS_OK(result)) {
482 werr = ntstatus_to_werror(result);
486 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
487 if (!NT_STATUS_IS_OK(status)) {
488 werr = ntstatus_to_werror(status);
492 uX.usriX_flags |= ACB_NORMAL;
494 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
498 if (!NT_STATUS_IS_OK(status)) {
499 werr = ntstatus_to_werror(status);
507 dcerpc_samr_DeleteUser(b, talloc_tos(),
512 if (is_valid_policy_hnd(&user_handle) && b) {
513 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
516 if (ctx->disable_policy_handle_cache) {
517 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
518 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
524 /****************************************************************
525 ****************************************************************/
527 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
528 struct NetUserAdd *r)
530 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
533 /****************************************************************
534 ****************************************************************/
536 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
537 struct NetUserDel *r)
539 struct rpc_pipe_client *pipe_cli = NULL;
540 NTSTATUS status, result;
542 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
543 struct lsa_String lsa_account_name;
544 struct samr_Ids user_rids, name_types;
545 struct dom_sid2 *domain_sid = NULL;
546 struct dom_sid2 user_sid;
547 struct dcerpc_binding_handle *b = NULL;
549 ZERO_STRUCT(connect_handle);
550 ZERO_STRUCT(builtin_handle);
551 ZERO_STRUCT(domain_handle);
552 ZERO_STRUCT(user_handle);
554 werr = libnetapi_open_pipe(ctx, r->in.server_name,
558 if (!W_ERROR_IS_OK(werr)) {
562 b = pipe_cli->binding_handle;
564 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
565 SAMR_ACCESS_ENUM_DOMAINS |
566 SAMR_ACCESS_LOOKUP_DOMAIN,
567 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
571 if (!W_ERROR_IS_OK(werr)) {
575 status = dcerpc_samr_OpenDomain(b, talloc_tos(),
577 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
578 discard_const_p(struct dom_sid, &global_sid_Builtin),
581 if (!NT_STATUS_IS_OK(status)) {
582 werr = ntstatus_to_werror(status);
585 if (!NT_STATUS_IS_OK(result)) {
586 werr = ntstatus_to_werror(result);
590 init_lsa_String(&lsa_account_name, r->in.user_name);
592 status = dcerpc_samr_LookupNames(b, talloc_tos(),
599 if (!NT_STATUS_IS_OK(status)) {
600 werr = ntstatus_to_werror(status);
603 if (!NT_STATUS_IS_OK(result)) {
604 werr = ntstatus_to_werror(result);
607 if (user_rids.count != 1) {
608 werr = WERR_BAD_NET_RESP;
611 if (name_types.count != 1) {
612 werr = WERR_BAD_NET_RESP;
616 status = dcerpc_samr_OpenUser(b, talloc_tos(),
622 if (!NT_STATUS_IS_OK(status)) {
623 werr = ntstatus_to_werror(status);
626 if (!NT_STATUS_IS_OK(result)) {
627 werr = ntstatus_to_werror(result);
631 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
633 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, talloc_tos(),
637 if (!NT_STATUS_IS_OK(status)) {
638 werr = ntstatus_to_werror(status);
641 if (!NT_STATUS_IS_OK(result)) {
642 werr = ntstatus_to_werror(result);
646 status = dcerpc_samr_DeleteUser(b, talloc_tos(),
649 if (!NT_STATUS_IS_OK(status)) {
650 werr = ntstatus_to_werror(status);
653 if (!NT_STATUS_IS_OK(result)) {
654 werr = ntstatus_to_werror(result);
661 if (is_valid_policy_hnd(&user_handle)) {
662 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
665 if (ctx->disable_policy_handle_cache) {
666 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
667 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
668 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
674 /****************************************************************
675 ****************************************************************/
677 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
678 struct NetUserDel *r)
680 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
683 /****************************************************************
684 ****************************************************************/
686 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
687 struct rpc_pipe_client *pipe_cli,
688 struct policy_handle *domain_handle,
689 struct policy_handle *builtin_handle,
690 const char *user_name,
691 const struct dom_sid *domain_sid,
694 struct samr_UserInfo21 **info21,
695 struct sec_desc_buf **sec_desc,
696 uint32_t *auth_flag_p)
698 NTSTATUS status, result;
700 struct policy_handle user_handle;
701 union samr_UserInfo *user_info = NULL;
702 struct samr_RidWithAttributeArray *rid_array = NULL;
703 uint32_t access_mask = SEC_STD_READ_CONTROL |
704 SAMR_USER_ACCESS_GET_ATTRIBUTES |
705 SAMR_USER_ACCESS_GET_NAME_ETC;
706 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
708 ZERO_STRUCT(user_handle);
714 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
715 SAMR_USER_ACCESS_GET_GROUPS;
721 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
722 SAMR_USER_ACCESS_GET_GROUPS |
723 SAMR_USER_ACCESS_GET_LOCALE;
730 return NT_STATUS_INVALID_LEVEL;
737 status = dcerpc_samr_OpenUser(b, mem_ctx,
743 if (!NT_STATUS_IS_OK(status)) {
746 if (!NT_STATUS_IS_OK(result)) {
751 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
756 if (!NT_STATUS_IS_OK(status)) {
759 if (!NT_STATUS_IS_OK(result)) {
764 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
769 if (!NT_STATUS_IS_OK(status)) {
772 if (!NT_STATUS_IS_OK(result)) {
777 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
779 struct lsa_SidArray sid_array;
780 struct samr_Ids alias_rids;
782 uint32_t auth_flag = 0;
785 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
789 if (!NT_STATUS_IS_OK(status)) {
792 if (!NT_STATUS_IS_OK(result)) {
797 sid_array.num_sids = rid_array->count + 1;
798 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
800 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
802 for (i=0; i<rid_array->count; i++) {
803 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
804 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
805 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
808 sid_compose(&sid, domain_sid, rid);
809 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
810 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
812 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
817 if (!NT_STATUS_IS_OK(status)) {
820 if (!NT_STATUS_IS_OK(result)) {
825 for (i=0; i<alias_rids.count; i++) {
826 switch (alias_rids.ids[i]) {
827 case 550: /* Print Operators */
828 auth_flag |= AF_OP_PRINT;
830 case 549: /* Server Operators */
831 auth_flag |= AF_OP_SERVER;
833 case 548: /* Account Operators */
834 auth_flag |= AF_OP_ACCOUNTS;
842 *auth_flag_p = auth_flag;
846 *info21 = &user_info->info21;
849 if (is_valid_policy_hnd(&user_handle)) {
850 dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
856 /****************************************************************
857 ****************************************************************/
859 static uint32_t samr_rid_to_priv_level(uint32_t rid)
862 case DOMAIN_RID_ADMINISTRATOR:
863 return USER_PRIV_ADMIN;
864 case DOMAIN_RID_GUEST:
865 return USER_PRIV_GUEST;
867 return USER_PRIV_USER;
871 /****************************************************************
872 ****************************************************************/
874 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
876 uint32_t fl = UF_SCRIPT; /* god knows why */
878 fl |= ds_acb2uf(acb);
883 /****************************************************************
884 ****************************************************************/
886 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
887 const struct samr_UserInfo21 *i21,
888 struct USER_INFO_1 *i)
891 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
892 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
893 i->usri1_password = NULL;
894 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
895 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
896 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
897 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
898 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
899 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
904 /****************************************************************
905 ****************************************************************/
907 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
908 const struct samr_UserInfo21 *i21,
910 struct USER_INFO_2 *i)
914 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
915 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
916 i->usri2_password = NULL;
917 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
918 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
919 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
920 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
921 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
922 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
923 i->usri2_auth_flags = auth_flag;
924 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
925 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
926 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
927 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
928 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
929 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
930 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
931 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
932 i->usri2_units_per_week = i21->logon_hours.units_per_week;
933 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
934 i->usri2_bad_pw_count = i21->bad_password_count;
935 i->usri2_num_logons = i21->logon_count;
936 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
937 i->usri2_country_code = i21->country_code;
938 i->usri2_code_page = i21->code_page;
943 /****************************************************************
944 ****************************************************************/
946 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
947 const struct samr_UserInfo21 *i21,
949 struct USER_INFO_3 *i)
953 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
954 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
955 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
956 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
957 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
958 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
959 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
960 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
961 i->usri3_auth_flags = auth_flag;
962 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
963 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
964 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
965 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
966 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
967 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
968 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
969 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
970 i->usri3_units_per_week = i21->logon_hours.units_per_week;
971 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
972 i->usri3_bad_pw_count = i21->bad_password_count;
973 i->usri3_num_logons = i21->logon_count;
974 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
975 i->usri3_country_code = i21->country_code;
976 i->usri3_code_page = i21->code_page;
977 i->usri3_user_id = i21->rid;
978 i->usri3_primary_group_id = i21->primary_gid;
979 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
980 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
981 i->usri3_password_expired = i21->password_expired;
986 /****************************************************************
987 ****************************************************************/
989 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
990 const struct samr_UserInfo21 *i21,
992 struct dom_sid *domain_sid,
993 struct USER_INFO_4 *i)
999 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
1000 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
1001 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1002 i->usri4_password = NULL;
1003 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
1004 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1005 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
1006 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1007 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
1008 i->usri4_auth_flags = auth_flag;
1009 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1010 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1011 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1012 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1013 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
1014 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
1015 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
1016 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1017 i->usri4_units_per_week = i21->logon_hours.units_per_week;
1018 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1019 i->usri4_bad_pw_count = i21->bad_password_count;
1020 i->usri4_num_logons = i21->logon_count;
1021 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1022 i->usri4_country_code = i21->country_code;
1023 i->usri4_code_page = i21->code_page;
1024 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1025 return NT_STATUS_NO_MEMORY;
1027 i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1028 i->usri4_primary_group_id = i21->primary_gid;
1029 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
1030 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
1031 i->usri4_password_expired = i21->password_expired;
1033 return NT_STATUS_OK;
1036 /****************************************************************
1037 ****************************************************************/
1039 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
1040 const struct samr_UserInfo21 *i21,
1041 struct USER_INFO_10 *i)
1045 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
1046 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
1047 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
1048 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1049 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1051 return NT_STATUS_OK;
1054 /****************************************************************
1055 ****************************************************************/
1057 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
1058 const struct samr_UserInfo21 *i21,
1060 struct USER_INFO_11 *i)
1064 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
1065 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
1066 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
1067 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1068 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1069 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
1070 i->usri11_auth_flags = auth_flag;
1071 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1072 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1073 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1074 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
1075 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
1076 i->usri11_bad_pw_count = i21->bad_password_count;
1077 i->usri11_num_logons = i21->logon_count;
1078 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1079 i->usri11_country_code = i21->country_code;
1080 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1081 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1082 i->usri11_units_per_week = i21->logon_hours.units_per_week;
1083 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1084 i->usri11_code_page = i21->code_page;
1086 return NT_STATUS_OK;
1089 /****************************************************************
1090 ****************************************************************/
1092 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
1093 const struct samr_UserInfo21 *i21,
1094 struct USER_INFO_20 *i)
1098 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1099 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1100 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1101 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1102 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1103 i->usri20_user_id = i21->rid;
1105 return NT_STATUS_OK;
1108 /****************************************************************
1109 ****************************************************************/
1111 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1112 const struct samr_UserInfo21 *i21,
1113 struct dom_sid *domain_sid,
1114 struct USER_INFO_23 *i)
1120 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1121 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1122 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1123 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1124 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1125 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1126 return NT_STATUS_NO_MEMORY;
1128 i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1130 return NT_STATUS_OK;
1133 /****************************************************************
1134 ****************************************************************/
1136 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1137 struct rpc_pipe_client *pipe_cli,
1138 struct dom_sid *domain_sid,
1139 struct policy_handle *domain_handle,
1140 struct policy_handle *builtin_handle,
1141 const char *user_name,
1145 uint32_t *num_entries)
1149 struct samr_UserInfo21 *info21 = NULL;
1150 struct sec_desc_buf *sec_desc = NULL;
1151 uint32_t auth_flag = 0;
1153 struct USER_INFO_0 info0;
1154 struct USER_INFO_1 info1;
1155 struct USER_INFO_2 info2;
1156 struct USER_INFO_3 info3;
1157 struct USER_INFO_4 info4;
1158 struct USER_INFO_10 info10;
1159 struct USER_INFO_11 info11;
1160 struct USER_INFO_20 info20;
1161 struct USER_INFO_23 info23;
1175 return NT_STATUS_INVALID_LEVEL;
1179 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1180 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1182 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1183 (struct USER_INFO_0 **)buffer, num_entries);
1185 return NT_STATUS_OK;
1188 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1199 if (!NT_STATUS_IS_OK(status)) {
1205 /* already returned above */
1208 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1209 NT_STATUS_NOT_OK_RETURN(status);
1211 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1212 (struct USER_INFO_1 **)buffer, num_entries);
1216 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1217 NT_STATUS_NOT_OK_RETURN(status);
1219 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1220 (struct USER_INFO_2 **)buffer, num_entries);
1224 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1225 NT_STATUS_NOT_OK_RETURN(status);
1227 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1228 (struct USER_INFO_3 **)buffer, num_entries);
1232 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1233 NT_STATUS_NOT_OK_RETURN(status);
1235 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1236 (struct USER_INFO_4 **)buffer, num_entries);
1240 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1241 NT_STATUS_NOT_OK_RETURN(status);
1243 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1244 (struct USER_INFO_10 **)buffer, num_entries);
1248 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1249 NT_STATUS_NOT_OK_RETURN(status);
1251 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1252 (struct USER_INFO_11 **)buffer, num_entries);
1256 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1257 NT_STATUS_NOT_OK_RETURN(status);
1259 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1260 (struct USER_INFO_20 **)buffer, num_entries);
1264 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1265 NT_STATUS_NOT_OK_RETURN(status);
1267 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1268 (struct USER_INFO_23 **)buffer, num_entries);
1271 return NT_STATUS_INVALID_LEVEL;
1278 /****************************************************************
1279 ****************************************************************/
1281 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1282 struct NetUserEnum *r)
1284 struct rpc_pipe_client *pipe_cli = NULL;
1285 struct policy_handle connect_handle;
1286 struct dom_sid2 *domain_sid = NULL;
1287 struct policy_handle domain_handle, builtin_handle;
1288 struct samr_SamArray *sam = NULL;
1289 uint32_t filter = ACB_NORMAL;
1291 uint32_t entries_read = 0;
1293 NTSTATUS status = NT_STATUS_OK;
1294 NTSTATUS result = NT_STATUS_OK;
1296 struct dcerpc_binding_handle *b = NULL;
1298 ZERO_STRUCT(connect_handle);
1299 ZERO_STRUCT(domain_handle);
1300 ZERO_STRUCT(builtin_handle);
1302 if (!r->out.buffer) {
1303 return WERR_INVALID_PARAM;
1306 *r->out.buffer = NULL;
1307 *r->out.entries_read = 0;
1309 switch (r->in.level) {
1321 return WERR_UNKNOWN_LEVEL;
1324 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1327 if (!W_ERROR_IS_OK(werr)) {
1331 b = pipe_cli->binding_handle;
1333 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1334 SAMR_ACCESS_ENUM_DOMAINS |
1335 SAMR_ACCESS_LOOKUP_DOMAIN,
1336 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1337 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1340 if (!W_ERROR_IS_OK(werr)) {
1344 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1345 SAMR_ACCESS_ENUM_DOMAINS |
1346 SAMR_ACCESS_LOOKUP_DOMAIN,
1347 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1348 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1349 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1353 if (!W_ERROR_IS_OK(werr)) {
1357 switch (r->in.filter) {
1358 case FILTER_NORMAL_ACCOUNT:
1359 filter = ACB_NORMAL;
1361 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1362 filter = ACB_TEMPDUP;
1364 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1365 filter = ACB_DOMTRUST;
1367 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1368 filter = ACB_WSTRUST;
1370 case FILTER_SERVER_TRUST_ACCOUNT:
1371 filter = ACB_SVRTRUST;
1377 status = dcerpc_samr_EnumDomainUsers(b,
1380 r->in.resume_handle,
1386 if (!NT_STATUS_IS_OK(status)) {
1387 werr = ntstatus_to_werror(status);
1390 werr = ntstatus_to_werror(result);
1391 if (NT_STATUS_IS_ERR(result)) {
1395 for (i=0; i < sam->count; i++) {
1397 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1401 sam->entries[i].name.string,
1402 sam->entries[i].idx,
1405 r->out.entries_read);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 werr = ntstatus_to_werror(status);
1414 if (NT_STATUS_IS_OK(result) ||
1415 NT_STATUS_IS_ERR(result)) {
1417 if (ctx->disable_policy_handle_cache) {
1418 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1419 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1420 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1427 /****************************************************************
1428 ****************************************************************/
1430 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1431 struct NetUserEnum *r)
1433 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1436 /****************************************************************
1437 ****************************************************************/
1439 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1440 struct samr_DispInfoGeneral *info,
1441 uint32_t *entries_read,
1444 struct NET_DISPLAY_USER *user = NULL;
1447 user = talloc_zero_array(mem_ctx,
1448 struct NET_DISPLAY_USER,
1450 W_ERROR_HAVE_NO_MEMORY(user);
1452 for (i = 0; i < info->count; i++) {
1453 user[i].usri1_name = talloc_strdup(mem_ctx,
1454 info->entries[i].account_name.string);
1455 user[i].usri1_comment = talloc_strdup(mem_ctx,
1456 info->entries[i].description.string);
1457 user[i].usri1_flags =
1458 info->entries[i].acct_flags;
1459 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1460 info->entries[i].full_name.string);
1461 user[i].usri1_user_id =
1462 info->entries[i].rid;
1463 user[i].usri1_next_index =
1464 info->entries[i].idx;
1466 if (!user[i].usri1_name) {
1471 *buffer = talloc_memdup(mem_ctx, user,
1472 sizeof(struct NET_DISPLAY_USER) * info->count);
1473 W_ERROR_HAVE_NO_MEMORY(*buffer);
1475 *entries_read = info->count;
1480 /****************************************************************
1481 ****************************************************************/
1483 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1484 struct samr_DispInfoFull *info,
1485 uint32_t *entries_read,
1488 struct NET_DISPLAY_MACHINE *machine = NULL;
1491 machine = talloc_zero_array(mem_ctx,
1492 struct NET_DISPLAY_MACHINE,
1494 W_ERROR_HAVE_NO_MEMORY(machine);
1496 for (i = 0; i < info->count; i++) {
1497 machine[i].usri2_name = talloc_strdup(mem_ctx,
1498 info->entries[i].account_name.string);
1499 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1500 info->entries[i].description.string);
1501 machine[i].usri2_flags =
1502 info->entries[i].acct_flags;
1503 machine[i].usri2_user_id =
1504 info->entries[i].rid;
1505 machine[i].usri2_next_index =
1506 info->entries[i].idx;
1508 if (!machine[i].usri2_name) {
1513 *buffer = talloc_memdup(mem_ctx, machine,
1514 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1515 W_ERROR_HAVE_NO_MEMORY(*buffer);
1517 *entries_read = info->count;
1522 /****************************************************************
1523 ****************************************************************/
1525 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1526 struct samr_DispInfoFullGroups *info,
1527 uint32_t *entries_read,
1530 struct NET_DISPLAY_GROUP *group = NULL;
1533 group = talloc_zero_array(mem_ctx,
1534 struct NET_DISPLAY_GROUP,
1536 W_ERROR_HAVE_NO_MEMORY(group);
1538 for (i = 0; i < info->count; i++) {
1539 group[i].grpi3_name = talloc_strdup(mem_ctx,
1540 info->entries[i].account_name.string);
1541 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1542 info->entries[i].description.string);
1543 group[i].grpi3_group_id =
1544 info->entries[i].rid;
1545 group[i].grpi3_attributes =
1546 info->entries[i].acct_flags;
1547 group[i].grpi3_next_index =
1548 info->entries[i].idx;
1550 if (!group[i].grpi3_name) {
1555 *buffer = talloc_memdup(mem_ctx, group,
1556 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1557 W_ERROR_HAVE_NO_MEMORY(*buffer);
1559 *entries_read = info->count;
1565 /****************************************************************
1566 ****************************************************************/
1568 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1569 union samr_DispInfo *info,
1571 uint32_t *entries_read,
1576 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1581 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1586 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1594 return WERR_UNKNOWN_LEVEL;
1597 /****************************************************************
1598 ****************************************************************/
1600 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1601 struct NetQueryDisplayInformation *r)
1603 struct rpc_pipe_client *pipe_cli = NULL;
1604 struct policy_handle connect_handle;
1605 struct dom_sid2 *domain_sid = NULL;
1606 struct policy_handle domain_handle;
1607 union samr_DispInfo info;
1608 struct dcerpc_binding_handle *b = NULL;
1610 uint32_t total_size = 0;
1611 uint32_t returned_size = 0;
1613 NTSTATUS status = NT_STATUS_OK;
1614 NTSTATUS result = NT_STATUS_OK;
1618 *r->out.entries_read = 0;
1620 ZERO_STRUCT(connect_handle);
1621 ZERO_STRUCT(domain_handle);
1623 switch (r->in.level) {
1629 return WERR_UNKNOWN_LEVEL;
1632 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1635 if (!W_ERROR_IS_OK(werr)) {
1639 b = pipe_cli->binding_handle;
1641 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1642 SAMR_ACCESS_ENUM_DOMAINS |
1643 SAMR_ACCESS_LOOKUP_DOMAIN,
1644 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1645 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1646 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1650 if (!W_ERROR_IS_OK(werr)) {
1654 status = dcerpc_samr_QueryDisplayInfo2(b,
1659 r->in.entries_requested,
1665 if (!NT_STATUS_IS_OK(status)) {
1666 werr = ntstatus_to_werror(status);
1669 werr = ntstatus_to_werror(result);
1670 if (NT_STATUS_IS_ERR(result)) {
1674 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1676 r->out.entries_read,
1678 if (!W_ERROR_IS_OK(werr_tmp)) {
1683 if (NT_STATUS_IS_OK(result) ||
1684 NT_STATUS_IS_ERR(result)) {
1686 if (ctx->disable_policy_handle_cache) {
1687 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1688 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1696 /****************************************************************
1697 ****************************************************************/
1700 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1701 struct NetQueryDisplayInformation *r)
1703 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1706 /****************************************************************
1707 ****************************************************************/
1709 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1710 struct NetUserChangePassword *r)
1712 return WERR_NOT_SUPPORTED;
1715 /****************************************************************
1716 ****************************************************************/
1718 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1719 struct NetUserChangePassword *r)
1721 return WERR_NOT_SUPPORTED;
1724 /****************************************************************
1725 ****************************************************************/
1727 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1728 struct NetUserGetInfo *r)
1730 struct rpc_pipe_client *pipe_cli = NULL;
1731 NTSTATUS status, result;
1734 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1735 struct lsa_String lsa_account_name;
1736 struct dom_sid2 *domain_sid = NULL;
1737 struct samr_Ids user_rids, name_types;
1738 uint32_t num_entries = 0;
1739 struct dcerpc_binding_handle *b = NULL;
1741 ZERO_STRUCT(connect_handle);
1742 ZERO_STRUCT(domain_handle);
1743 ZERO_STRUCT(builtin_handle);
1744 ZERO_STRUCT(user_handle);
1746 if (!r->out.buffer) {
1747 return WERR_INVALID_PARAM;
1750 switch (r->in.level) {
1762 werr = WERR_UNKNOWN_LEVEL;
1766 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1769 if (!W_ERROR_IS_OK(werr)) {
1773 b = pipe_cli->binding_handle;
1775 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1776 SAMR_ACCESS_ENUM_DOMAINS |
1777 SAMR_ACCESS_LOOKUP_DOMAIN,
1778 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1782 if (!W_ERROR_IS_OK(werr)) {
1786 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1787 SAMR_ACCESS_ENUM_DOMAINS |
1788 SAMR_ACCESS_LOOKUP_DOMAIN,
1789 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1790 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1793 if (!W_ERROR_IS_OK(werr)) {
1797 init_lsa_String(&lsa_account_name, r->in.user_name);
1799 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1806 if (!NT_STATUS_IS_OK(status)) {
1807 werr = ntstatus_to_werror(status);
1810 if (!NT_STATUS_IS_OK(result)) {
1811 werr = ntstatus_to_werror(result);
1814 if (user_rids.count != 1) {
1815 werr = WERR_BAD_NET_RESP;
1818 if (name_types.count != 1) {
1819 werr = WERR_BAD_NET_RESP;
1823 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1832 if (!NT_STATUS_IS_OK(status)) {
1833 werr = ntstatus_to_werror(status);
1838 if (is_valid_policy_hnd(&user_handle) && b) {
1839 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1842 if (ctx->disable_policy_handle_cache) {
1843 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1844 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1850 /****************************************************************
1851 ****************************************************************/
1853 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1854 struct NetUserGetInfo *r)
1856 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1859 /****************************************************************
1860 ****************************************************************/
1862 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1863 struct NetUserSetInfo *r)
1865 struct rpc_pipe_client *pipe_cli = NULL;
1866 NTSTATUS status, result;
1869 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1870 struct lsa_String lsa_account_name;
1871 struct dom_sid2 *domain_sid = NULL;
1872 struct samr_Ids user_rids, name_types;
1873 uint32_t user_mask = 0;
1875 struct USER_INFO_X uX;
1876 struct dcerpc_binding_handle *b = NULL;
1877 DATA_BLOB session_key;
1879 ZERO_STRUCT(connect_handle);
1880 ZERO_STRUCT(domain_handle);
1881 ZERO_STRUCT(builtin_handle);
1882 ZERO_STRUCT(user_handle);
1884 if (!r->in.buffer) {
1885 return WERR_INVALID_PARAM;
1888 switch (r->in.level) {
1890 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1893 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1902 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1906 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1909 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1910 SAMR_USER_ACCESS_GET_GROUPS;
1913 user_mask = SEC_STD_READ_CONTROL |
1915 SAMR_USER_ACCESS_GET_GROUPS |
1916 SAMR_USER_ACCESS_SET_PASSWORD |
1917 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1918 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1919 SAMR_USER_ACCESS_SET_LOC_COM;
1931 werr = WERR_NOT_SUPPORTED;
1934 werr = WERR_UNKNOWN_LEVEL;
1938 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1941 if (!W_ERROR_IS_OK(werr)) {
1945 b = pipe_cli->binding_handle;
1947 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1948 SAMR_ACCESS_ENUM_DOMAINS |
1949 SAMR_ACCESS_LOOKUP_DOMAIN,
1950 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1951 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1955 if (!W_ERROR_IS_OK(werr)) {
1959 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1960 SAMR_ACCESS_ENUM_DOMAINS |
1961 SAMR_ACCESS_LOOKUP_DOMAIN,
1962 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1963 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1966 if (!W_ERROR_IS_OK(werr)) {
1970 init_lsa_String(&lsa_account_name, r->in.user_name);
1972 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1979 if (!NT_STATUS_IS_OK(status)) {
1980 werr = ntstatus_to_werror(status);
1983 if (!NT_STATUS_IS_OK(result)) {
1984 werr = ntstatus_to_werror(result);
1987 if (user_rids.count != 1) {
1988 werr = WERR_BAD_NET_RESP;
1991 if (name_types.count != 1) {
1992 werr = WERR_BAD_NET_RESP;
1996 status = dcerpc_samr_OpenUser(b, talloc_tos(),
2002 if (!NT_STATUS_IS_OK(status)) {
2003 werr = ntstatus_to_werror(status);
2006 if (!NT_STATUS_IS_OK(result)) {
2007 werr = ntstatus_to_werror(result);
2011 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
2012 if (!NT_STATUS_IS_OK(status)) {
2013 werr = ntstatus_to_werror(status);
2017 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 werr = ntstatus_to_werror(status);
2023 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
2027 if (!NT_STATUS_IS_OK(status)) {
2028 werr = ntstatus_to_werror(status);
2035 if (is_valid_policy_hnd(&user_handle) && b) {
2036 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
2039 if (ctx->disable_policy_handle_cache) {
2040 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2041 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
2042 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2048 /****************************************************************
2049 ****************************************************************/
2051 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
2052 struct NetUserSetInfo *r)
2054 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
2057 /****************************************************************
2058 ****************************************************************/
2060 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2061 struct rpc_pipe_client *pipe_cli,
2062 struct policy_handle *domain_handle,
2063 struct samr_DomInfo1 *info1,
2064 struct samr_DomInfo3 *info3,
2065 struct samr_DomInfo5 *info5,
2066 struct samr_DomInfo6 *info6,
2067 struct samr_DomInfo7 *info7,
2068 struct samr_DomInfo12 *info12)
2070 NTSTATUS status, result;
2071 union samr_DomainInfo *dom_info = NULL;
2072 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2075 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2080 NT_STATUS_NOT_OK_RETURN(status);
2081 NT_STATUS_NOT_OK_RETURN(result);
2083 *info1 = dom_info->info1;
2087 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2092 NT_STATUS_NOT_OK_RETURN(status);
2093 NT_STATUS_NOT_OK_RETURN(result);
2095 *info3 = dom_info->info3;
2099 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2104 NT_STATUS_NOT_OK_RETURN(status);
2105 NT_STATUS_NOT_OK_RETURN(result);
2107 *info5 = dom_info->info5;
2111 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2116 NT_STATUS_NOT_OK_RETURN(status);
2117 NT_STATUS_NOT_OK_RETURN(result);
2119 *info6 = dom_info->info6;
2123 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2128 NT_STATUS_NOT_OK_RETURN(status);
2129 NT_STATUS_NOT_OK_RETURN(result);
2131 *info7 = dom_info->info7;
2135 status = dcerpc_samr_QueryDomainInfo2(b, mem_ctx,
2140 NT_STATUS_NOT_OK_RETURN(status);
2141 NT_STATUS_NOT_OK_RETURN(result);
2143 *info12 = dom_info->info12;
2146 return NT_STATUS_OK;
2149 /****************************************************************
2150 ****************************************************************/
2152 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
2153 struct rpc_pipe_client *pipe_cli,
2154 struct policy_handle *domain_handle,
2155 struct USER_MODALS_INFO_0 *info0)
2158 struct samr_DomInfo1 dom_info1;
2159 struct samr_DomInfo3 dom_info3;
2161 ZERO_STRUCTP(info0);
2163 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2172 NT_STATUS_NOT_OK_RETURN(status);
2174 info0->usrmod0_min_passwd_len =
2175 dom_info1.min_password_length;
2176 info0->usrmod0_max_passwd_age =
2177 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2178 info0->usrmod0_min_passwd_age =
2179 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2180 info0->usrmod0_password_hist_len =
2181 dom_info1.password_history_length;
2183 info0->usrmod0_force_logoff =
2184 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2186 return NT_STATUS_OK;
2189 /****************************************************************
2190 ****************************************************************/
2192 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2193 struct rpc_pipe_client *pipe_cli,
2194 struct policy_handle *domain_handle,
2195 struct USER_MODALS_INFO_1 *info1)
2198 struct samr_DomInfo6 dom_info6;
2199 struct samr_DomInfo7 dom_info7;
2201 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2210 NT_STATUS_NOT_OK_RETURN(status);
2212 info1->usrmod1_primary =
2213 talloc_strdup(mem_ctx, dom_info6.primary.string);
2215 info1->usrmod1_role = dom_info7.role;
2217 return NT_STATUS_OK;
2220 /****************************************************************
2221 ****************************************************************/
2223 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2224 struct rpc_pipe_client *pipe_cli,
2225 struct policy_handle *domain_handle,
2226 struct dom_sid *domain_sid,
2227 struct USER_MODALS_INFO_2 *info2)
2230 struct samr_DomInfo5 dom_info5;
2232 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2241 NT_STATUS_NOT_OK_RETURN(status);
2243 info2->usrmod2_domain_name =
2244 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2245 info2->usrmod2_domain_id =
2246 (struct domsid *)dom_sid_dup(mem_ctx, domain_sid);
2248 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2249 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2251 return NT_STATUS_OK;
2254 /****************************************************************
2255 ****************************************************************/
2257 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2258 struct rpc_pipe_client *pipe_cli,
2259 struct policy_handle *domain_handle,
2260 struct USER_MODALS_INFO_3 *info3)
2263 struct samr_DomInfo12 dom_info12;
2265 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2274 NT_STATUS_NOT_OK_RETURN(status);
2276 info3->usrmod3_lockout_duration =
2277 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2278 info3->usrmod3_lockout_observation_window =
2279 nt_time_to_unix_abs(&dom_info12.lockout_window);
2280 info3->usrmod3_lockout_threshold =
2281 dom_info12.lockout_threshold;
2283 return NT_STATUS_OK;
2286 /****************************************************************
2287 ****************************************************************/
2289 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2290 struct rpc_pipe_client *pipe_cli,
2292 struct policy_handle *domain_handle,
2293 struct dom_sid *domain_sid,
2298 struct USER_MODALS_INFO_0 info0;
2299 struct USER_MODALS_INFO_1 info1;
2300 struct USER_MODALS_INFO_2 info2;
2301 struct USER_MODALS_INFO_3 info3;
2304 return ERROR_INSUFFICIENT_BUFFER;
2309 status = query_USER_MODALS_INFO_0(mem_ctx,
2313 NT_STATUS_NOT_OK_RETURN(status);
2315 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2320 status = query_USER_MODALS_INFO_1(mem_ctx,
2324 NT_STATUS_NOT_OK_RETURN(status);
2326 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2330 status = query_USER_MODALS_INFO_2(mem_ctx,
2335 NT_STATUS_NOT_OK_RETURN(status);
2337 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2341 status = query_USER_MODALS_INFO_3(mem_ctx,
2345 NT_STATUS_NOT_OK_RETURN(status);
2347 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2354 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2356 return NT_STATUS_OK;
2359 /****************************************************************
2360 ****************************************************************/
2362 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2363 struct NetUserModalsGet *r)
2365 struct rpc_pipe_client *pipe_cli = NULL;
2369 struct policy_handle connect_handle, domain_handle;
2370 struct dom_sid2 *domain_sid = NULL;
2371 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2373 ZERO_STRUCT(connect_handle);
2374 ZERO_STRUCT(domain_handle);
2376 if (!r->out.buffer) {
2377 return WERR_INVALID_PARAM;
2380 switch (r->in.level) {
2382 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2383 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2387 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2390 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2393 werr = WERR_UNKNOWN_LEVEL;
2397 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2400 if (!W_ERROR_IS_OK(werr)) {
2404 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2405 SAMR_ACCESS_ENUM_DOMAINS |
2406 SAMR_ACCESS_LOOKUP_DOMAIN,
2411 if (!W_ERROR_IS_OK(werr)) {
2418 /* 3: 12 (DomainInfo2) */
2420 status = query_USER_MODALS_INFO_to_buffer(ctx,
2426 if (!NT_STATUS_IS_OK(status)) {
2427 werr = ntstatus_to_werror(status);
2432 if (ctx->disable_policy_handle_cache) {
2433 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2434 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2440 /****************************************************************
2441 ****************************************************************/
2443 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2444 struct NetUserModalsGet *r)
2446 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2449 /****************************************************************
2450 ****************************************************************/
2452 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2453 struct rpc_pipe_client *pipe_cli,
2454 struct policy_handle *domain_handle,
2455 struct samr_DomInfo1 *info1,
2456 struct samr_DomInfo3 *info3,
2457 struct samr_DomInfo12 *info12)
2459 NTSTATUS status, result;
2460 union samr_DomainInfo dom_info;
2461 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2465 ZERO_STRUCT(dom_info);
2467 dom_info.info1 = *info1;
2469 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2474 NT_STATUS_NOT_OK_RETURN(status);
2475 NT_STATUS_NOT_OK_RETURN(result);
2480 ZERO_STRUCT(dom_info);
2482 dom_info.info3 = *info3;
2484 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2490 NT_STATUS_NOT_OK_RETURN(status);
2491 NT_STATUS_NOT_OK_RETURN(result);
2496 ZERO_STRUCT(dom_info);
2498 dom_info.info12 = *info12;
2500 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2506 NT_STATUS_NOT_OK_RETURN(status);
2507 NT_STATUS_NOT_OK_RETURN(result);
2510 return NT_STATUS_OK;
2513 /****************************************************************
2514 ****************************************************************/
2516 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2517 struct rpc_pipe_client *pipe_cli,
2518 struct policy_handle *domain_handle,
2519 struct USER_MODALS_INFO_0 *info0)
2522 struct samr_DomInfo1 dom_info_1;
2523 struct samr_DomInfo3 dom_info_3;
2525 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2534 NT_STATUS_NOT_OK_RETURN(status);
2536 dom_info_1.min_password_length =
2537 info0->usrmod0_min_passwd_len;
2538 dom_info_1.password_history_length =
2539 info0->usrmod0_password_hist_len;
2541 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2542 info0->usrmod0_max_passwd_age);
2543 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2544 info0->usrmod0_min_passwd_age);
2546 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2547 info0->usrmod0_force_logoff);
2549 return set_USER_MODALS_INFO_rpc(mem_ctx,
2557 /****************************************************************
2558 ****************************************************************/
2560 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2561 struct rpc_pipe_client *pipe_cli,
2562 struct policy_handle *domain_handle,
2563 struct USER_MODALS_INFO_3 *info3)
2566 struct samr_DomInfo12 dom_info_12;
2568 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2577 NT_STATUS_NOT_OK_RETURN(status);
2579 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2580 info3->usrmod3_lockout_duration);
2581 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2582 info3->usrmod3_lockout_observation_window);
2583 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2585 return set_USER_MODALS_INFO_rpc(mem_ctx,
2593 /****************************************************************
2594 ****************************************************************/
2596 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2597 struct rpc_pipe_client *pipe_cli,
2598 struct policy_handle *domain_handle,
2599 struct USER_MODALS_INFO_1001 *info1001)
2602 struct samr_DomInfo1 dom_info_1;
2604 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2613 NT_STATUS_NOT_OK_RETURN(status);
2615 dom_info_1.min_password_length =
2616 info1001->usrmod1001_min_passwd_len;
2618 return set_USER_MODALS_INFO_rpc(mem_ctx,
2626 /****************************************************************
2627 ****************************************************************/
2629 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2630 struct rpc_pipe_client *pipe_cli,
2631 struct policy_handle *domain_handle,
2632 struct USER_MODALS_INFO_1002 *info1002)
2635 struct samr_DomInfo1 dom_info_1;
2637 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2646 NT_STATUS_NOT_OK_RETURN(status);
2648 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2649 info1002->usrmod1002_max_passwd_age);
2651 return set_USER_MODALS_INFO_rpc(mem_ctx,
2659 /****************************************************************
2660 ****************************************************************/
2662 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2663 struct rpc_pipe_client *pipe_cli,
2664 struct policy_handle *domain_handle,
2665 struct USER_MODALS_INFO_1003 *info1003)
2668 struct samr_DomInfo1 dom_info_1;
2670 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2679 NT_STATUS_NOT_OK_RETURN(status);
2681 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2682 info1003->usrmod1003_min_passwd_age);
2684 return set_USER_MODALS_INFO_rpc(mem_ctx,
2692 /****************************************************************
2693 ****************************************************************/
2695 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2696 struct rpc_pipe_client *pipe_cli,
2697 struct policy_handle *domain_handle,
2698 struct USER_MODALS_INFO_1004 *info1004)
2701 struct samr_DomInfo3 dom_info_3;
2703 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2712 NT_STATUS_NOT_OK_RETURN(status);
2714 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2715 info1004->usrmod1004_force_logoff);
2717 return set_USER_MODALS_INFO_rpc(mem_ctx,
2725 /****************************************************************
2726 ****************************************************************/
2728 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2729 struct rpc_pipe_client *pipe_cli,
2730 struct policy_handle *domain_handle,
2731 struct USER_MODALS_INFO_1005 *info1005)
2734 struct samr_DomInfo1 dom_info_1;
2736 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2745 NT_STATUS_NOT_OK_RETURN(status);
2747 dom_info_1.password_history_length =
2748 info1005->usrmod1005_password_hist_len;
2750 return set_USER_MODALS_INFO_rpc(mem_ctx,
2758 /****************************************************************
2759 ****************************************************************/
2761 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2762 struct rpc_pipe_client *pipe_cli,
2764 struct policy_handle *domain_handle,
2765 struct dom_sid *domain_sid,
2768 struct USER_MODALS_INFO_0 *info0;
2769 struct USER_MODALS_INFO_3 *info3;
2770 struct USER_MODALS_INFO_1001 *info1001;
2771 struct USER_MODALS_INFO_1002 *info1002;
2772 struct USER_MODALS_INFO_1003 *info1003;
2773 struct USER_MODALS_INFO_1004 *info1004;
2774 struct USER_MODALS_INFO_1005 *info1005;
2777 return ERROR_INSUFFICIENT_BUFFER;
2782 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2783 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2788 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2789 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2794 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2795 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2800 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2801 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2806 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2807 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2812 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2813 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2818 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2819 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2828 return NT_STATUS_OK;
2831 /****************************************************************
2832 ****************************************************************/
2834 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2835 struct NetUserModalsSet *r)
2837 struct rpc_pipe_client *pipe_cli = NULL;
2841 struct policy_handle connect_handle, domain_handle;
2842 struct dom_sid2 *domain_sid = NULL;
2843 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2845 ZERO_STRUCT(connect_handle);
2846 ZERO_STRUCT(domain_handle);
2848 if (!r->in.buffer) {
2849 return WERR_INVALID_PARAM;
2852 switch (r->in.level) {
2854 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2855 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2856 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2857 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2864 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2865 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2868 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2869 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2875 werr = WERR_NOT_SUPPORTED;
2878 werr = WERR_UNKNOWN_LEVEL;
2882 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2885 if (!W_ERROR_IS_OK(werr)) {
2889 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2890 SAMR_ACCESS_ENUM_DOMAINS |
2891 SAMR_ACCESS_LOOKUP_DOMAIN,
2896 if (!W_ERROR_IS_OK(werr)) {
2900 status = set_USER_MODALS_INFO_buffer(ctx,
2906 if (!NT_STATUS_IS_OK(status)) {
2907 werr = ntstatus_to_werror(status);
2912 if (ctx->disable_policy_handle_cache) {
2913 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2914 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2920 /****************************************************************
2921 ****************************************************************/
2923 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2924 struct NetUserModalsSet *r)
2926 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2929 /****************************************************************
2930 ****************************************************************/
2932 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2934 const char *group_name,
2935 uint32_t attributes,
2937 uint32_t *num_entries)
2939 struct GROUP_USERS_INFO_0 u0;
2940 struct GROUP_USERS_INFO_1 u1;
2945 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2946 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2948 u0.grui0_name = NULL;
2951 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2952 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2956 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2957 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2959 u1.grui1_name = NULL;
2962 u1.grui1_attributes = attributes;
2964 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2965 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2968 return NT_STATUS_INVALID_INFO_CLASS;
2971 return NT_STATUS_OK;
2974 /****************************************************************
2975 ****************************************************************/
2977 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2978 struct NetUserGetGroups *r)
2980 struct rpc_pipe_client *pipe_cli = NULL;
2981 struct policy_handle connect_handle, domain_handle, user_handle;
2982 struct lsa_String lsa_account_name;
2983 struct dom_sid2 *domain_sid = NULL;
2984 struct samr_Ids user_rids, name_types;
2985 struct samr_RidWithAttributeArray *rid_array = NULL;
2986 struct lsa_Strings names;
2987 struct samr_Ids types;
2988 uint32_t *rids = NULL;
2991 uint32_t entries_read = 0;
2993 NTSTATUS status = NT_STATUS_OK;
2994 NTSTATUS result = NT_STATUS_OK;
2996 struct dcerpc_binding_handle *b = NULL;
2998 ZERO_STRUCT(connect_handle);
2999 ZERO_STRUCT(domain_handle);
3001 if (!r->out.buffer) {
3002 return WERR_INVALID_PARAM;
3005 *r->out.buffer = NULL;
3006 *r->out.entries_read = 0;
3007 *r->out.total_entries = 0;
3009 switch (r->in.level) {
3014 return WERR_UNKNOWN_LEVEL;
3017 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3020 if (!W_ERROR_IS_OK(werr)) {
3024 b = pipe_cli->binding_handle;
3026 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3027 SAMR_ACCESS_ENUM_DOMAINS |
3028 SAMR_ACCESS_LOOKUP_DOMAIN,
3029 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3033 if (!W_ERROR_IS_OK(werr)) {
3037 init_lsa_String(&lsa_account_name, r->in.user_name);
3039 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3046 if (!NT_STATUS_IS_OK(status)) {
3047 werr = ntstatus_to_werror(status);
3050 if (!NT_STATUS_IS_OK(result)) {
3051 werr = ntstatus_to_werror(result);
3054 if (user_rids.count != 1) {
3055 werr = WERR_BAD_NET_RESP;
3058 if (name_types.count != 1) {
3059 werr = WERR_BAD_NET_RESP;
3063 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3065 SAMR_USER_ACCESS_GET_GROUPS,
3069 if (!NT_STATUS_IS_OK(status)) {
3070 werr = ntstatus_to_werror(status);
3073 if (!NT_STATUS_IS_OK(result)) {
3074 werr = ntstatus_to_werror(result);
3078 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3082 if (!NT_STATUS_IS_OK(status)) {
3083 werr = ntstatus_to_werror(status);
3086 if (!NT_STATUS_IS_OK(result)) {
3087 werr = ntstatus_to_werror(result);
3091 rids = talloc_array(ctx, uint32_t, rid_array->count);
3097 for (i=0; i < rid_array->count; i++) {
3098 rids[i] = rid_array->rids[i].rid;
3101 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3108 if (!NT_STATUS_IS_OK(status)) {
3109 werr = ntstatus_to_werror(status);
3112 if (!NT_STATUS_IS_OK(result) &&
3113 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3114 werr = ntstatus_to_werror(result);
3117 if (names.count != rid_array->count) {
3118 werr = WERR_BAD_NET_RESP;
3121 if (types.count != rid_array->count) {
3122 werr = WERR_BAD_NET_RESP;
3126 for (i=0; i < names.count; i++) {
3127 status = add_GROUP_USERS_INFO_X_buffer(ctx,
3129 names.names[i].string,
3130 rid_array->rids[i].attributes,
3133 if (!NT_STATUS_IS_OK(status)) {
3134 werr = ntstatus_to_werror(status);
3139 *r->out.entries_read = entries_read;
3140 *r->out.total_entries = entries_read;
3143 if (ctx->disable_policy_handle_cache) {
3144 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3145 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3151 /****************************************************************
3152 ****************************************************************/
3154 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
3155 struct NetUserGetGroups *r)
3157 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
3160 /****************************************************************
3161 ****************************************************************/
3163 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
3164 struct NetUserSetGroups *r)
3166 struct rpc_pipe_client *pipe_cli = NULL;
3167 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
3168 struct lsa_String lsa_account_name;
3169 struct dom_sid2 *domain_sid = NULL;
3170 struct samr_Ids user_rids, name_types;
3171 struct samr_Ids group_rids;
3172 struct samr_RidWithAttributeArray *rid_array = NULL;
3173 struct lsa_String *lsa_names = NULL;
3175 uint32_t *add_rids = NULL;
3176 uint32_t *del_rids = NULL;
3177 size_t num_add_rids = 0;
3178 size_t num_del_rids = 0;
3180 uint32_t *member_rids = NULL;
3182 struct GROUP_USERS_INFO_0 *i0 = NULL;
3183 struct GROUP_USERS_INFO_1 *i1 = NULL;
3187 NTSTATUS status = NT_STATUS_OK;
3188 NTSTATUS result = NT_STATUS_OK;
3190 struct dcerpc_binding_handle *b = NULL;
3192 ZERO_STRUCT(connect_handle);
3193 ZERO_STRUCT(domain_handle);
3194 ZERO_STRUCT(group_handle);
3196 if (!r->in.buffer) {
3197 return WERR_INVALID_PARAM;
3200 switch (r->in.level) {
3205 return WERR_UNKNOWN_LEVEL;
3208 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3211 if (!W_ERROR_IS_OK(werr)) {
3215 b = pipe_cli->binding_handle;
3217 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3218 SAMR_ACCESS_ENUM_DOMAINS |
3219 SAMR_ACCESS_LOOKUP_DOMAIN,
3220 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3224 if (!W_ERROR_IS_OK(werr)) {
3228 init_lsa_String(&lsa_account_name, r->in.user_name);
3230 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3237 if (!NT_STATUS_IS_OK(status)) {
3238 werr = ntstatus_to_werror(status);
3241 if (!NT_STATUS_IS_OK(result)) {
3242 werr = ntstatus_to_werror(result);
3245 if (user_rids.count != 1) {
3246 werr = WERR_BAD_NET_RESP;
3249 if (name_types.count != 1) {
3250 werr = WERR_BAD_NET_RESP;
3254 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3256 SAMR_USER_ACCESS_GET_GROUPS,
3260 if (!NT_STATUS_IS_OK(status)) {
3261 werr = ntstatus_to_werror(status);
3264 if (!NT_STATUS_IS_OK(result)) {
3265 werr = ntstatus_to_werror(result);
3269 switch (r->in.level) {
3271 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3274 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3278 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3284 for (i=0; i < r->in.num_entries; i++) {
3286 switch (r->in.level) {
3288 init_lsa_String(&lsa_names[i], i0->grui0_name);
3292 init_lsa_String(&lsa_names[i], i1->grui1_name);
3298 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3305 if (!NT_STATUS_IS_OK(status)) {
3306 werr = ntstatus_to_werror(status);
3309 if (!NT_STATUS_IS_OK(result)) {
3310 werr = ntstatus_to_werror(result);
3313 if (group_rids.count != r->in.num_entries) {
3314 werr = WERR_BAD_NET_RESP;
3317 if (name_types.count != r->in.num_entries) {
3318 werr = WERR_BAD_NET_RESP;
3322 member_rids = group_rids.ids;
3324 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3328 if (!NT_STATUS_IS_OK(status)) {
3329 werr = ntstatus_to_werror(status);
3332 if (!NT_STATUS_IS_OK(result)) {
3333 werr = ntstatus_to_werror(result);
3339 for (i=0; i < r->in.num_entries; i++) {
3340 bool already_member = false;
3341 for (k=0; k < rid_array->count; k++) {
3342 if (member_rids[i] == rid_array->rids[k].rid) {
3343 already_member = true;
3347 if (!already_member) {
3348 if (!add_rid_to_array_unique(ctx,
3350 &add_rids, &num_add_rids)) {
3351 werr = WERR_GENERAL_FAILURE;
3359 for (k=0; k < rid_array->count; k++) {
3360 bool keep_member = false;
3361 for (i=0; i < r->in.num_entries; i++) {
3362 if (member_rids[i] == rid_array->rids[k].rid) {
3368 if (!add_rid_to_array_unique(ctx,
3369 rid_array->rids[k].rid,
3370 &del_rids, &num_del_rids)) {
3371 werr = WERR_GENERAL_FAILURE;
3379 for (i=0; i < num_add_rids; i++) {
3380 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3382 SAMR_GROUP_ACCESS_ADD_MEMBER,
3386 if (!NT_STATUS_IS_OK(status)) {
3387 werr = ntstatus_to_werror(status);
3390 if (!NT_STATUS_IS_OK(result)) {
3391 werr = ntstatus_to_werror(result);
3395 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
3400 if (!NT_STATUS_IS_OK(status)) {
3401 werr = ntstatus_to_werror(status);
3404 if (!NT_STATUS_IS_OK(result)) {
3405 werr = ntstatus_to_werror(result);
3409 if (is_valid_policy_hnd(&group_handle)) {
3410 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3416 for (i=0; i < num_del_rids; i++) {
3417 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3419 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3423 if (!NT_STATUS_IS_OK(status)) {
3424 werr = ntstatus_to_werror(status);
3427 if (!NT_STATUS_IS_OK(result)) {
3428 werr = ntstatus_to_werror(result);
3432 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
3436 if (!NT_STATUS_IS_OK(status)) {
3437 werr = ntstatus_to_werror(status);
3440 if (!NT_STATUS_IS_OK(result)) {
3441 werr = ntstatus_to_werror(result);
3445 if (is_valid_policy_hnd(&group_handle)) {
3446 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3453 if (is_valid_policy_hnd(&group_handle)) {
3454 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3457 if (ctx->disable_policy_handle_cache) {
3458 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3459 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3465 /****************************************************************
3466 ****************************************************************/
3468 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3469 struct NetUserSetGroups *r)
3471 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3474 /****************************************************************
3475 ****************************************************************/
3477 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3479 const char *group_name,
3481 uint32_t *num_entries)
3483 struct LOCALGROUP_USERS_INFO_0 u0;
3487 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3488 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3490 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3491 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3494 return NT_STATUS_INVALID_INFO_CLASS;
3497 return NT_STATUS_OK;
3500 /****************************************************************
3501 ****************************************************************/
3503 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3504 struct NetUserGetLocalGroups *r)
3506 struct rpc_pipe_client *pipe_cli = NULL;
3507 struct policy_handle connect_handle, domain_handle, user_handle,
3509 struct lsa_String lsa_account_name;
3510 struct dom_sid2 *domain_sid = NULL;
3511 struct samr_Ids user_rids, name_types;
3512 struct samr_RidWithAttributeArray *rid_array = NULL;
3513 struct lsa_Strings names;
3514 struct samr_Ids types;
3515 uint32_t *rids = NULL;
3516 size_t num_rids = 0;
3517 struct dom_sid user_sid;
3518 struct lsa_SidArray sid_array;
3519 struct samr_Ids domain_rids;
3520 struct samr_Ids builtin_rids;
3523 uint32_t entries_read = 0;
3525 NTSTATUS status = NT_STATUS_OK;
3526 NTSTATUS result = NT_STATUS_OK;
3528 struct dcerpc_binding_handle *b = NULL;
3530 ZERO_STRUCT(connect_handle);
3531 ZERO_STRUCT(domain_handle);
3533 if (!r->out.buffer) {
3534 return WERR_INVALID_PARAM;
3537 *r->out.buffer = NULL;
3538 *r->out.entries_read = 0;
3539 *r->out.total_entries = 0;
3541 switch (r->in.level) {
3546 return WERR_UNKNOWN_LEVEL;
3549 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3552 if (!W_ERROR_IS_OK(werr)) {
3556 b = pipe_cli->binding_handle;
3558 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3559 SAMR_ACCESS_ENUM_DOMAINS |
3560 SAMR_ACCESS_LOOKUP_DOMAIN,
3561 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3562 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3566 if (!W_ERROR_IS_OK(werr)) {
3570 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3571 SAMR_ACCESS_ENUM_DOMAINS |
3572 SAMR_ACCESS_LOOKUP_DOMAIN,
3573 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3574 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3577 if (!W_ERROR_IS_OK(werr)) {
3581 init_lsa_String(&lsa_account_name, r->in.user_name);
3583 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3590 if (!NT_STATUS_IS_OK(status)) {
3591 werr = ntstatus_to_werror(status);
3594 if (!NT_STATUS_IS_OK(result)) {
3595 werr = ntstatus_to_werror(result);
3598 if (user_rids.count != 1) {
3599 werr = WERR_BAD_NET_RESP;
3602 if (name_types.count != 1) {
3603 werr = WERR_BAD_NET_RESP;
3607 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3609 SAMR_USER_ACCESS_GET_GROUPS,
3613 if (!NT_STATUS_IS_OK(status)) {
3614 werr = ntstatus_to_werror(status);
3617 if (!NT_STATUS_IS_OK(result)) {
3618 werr = ntstatus_to_werror(result);
3622 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3626 if (!NT_STATUS_IS_OK(status)) {
3627 werr = ntstatus_to_werror(status);
3630 if (!NT_STATUS_IS_OK(result)) {
3631 werr = ntstatus_to_werror(result);
3635 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3640 sid_array.num_sids = rid_array->count + 1;
3641 sid_array.sids = talloc_array(ctx, struct lsa_SidPtr, sid_array.num_sids);
3642 if (!sid_array.sids) {
3647 sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid);
3648 if (!sid_array.sids[0].sid) {
3653 for (i=0; i < rid_array->count; i++) {
3656 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3661 sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid);
3662 if (!sid_array.sids[i+1].sid) {
3668 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3673 if (!NT_STATUS_IS_OK(status)) {
3674 werr = ntstatus_to_werror(status);
3677 if (!NT_STATUS_IS_OK(result)) {
3678 werr = ntstatus_to_werror(result);
3682 for (i=0; i < domain_rids.count; i++) {
3683 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3684 &rids, &num_rids)) {
3690 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3695 if (!NT_STATUS_IS_OK(status)) {
3696 werr = ntstatus_to_werror(status);
3699 if (!NT_STATUS_IS_OK(result)) {
3700 werr = ntstatus_to_werror(result);
3704 for (i=0; i < builtin_rids.count; i++) {
3705 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3706 &rids, &num_rids)) {
3712 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3719 if (!NT_STATUS_IS_OK(status)) {
3720 werr = ntstatus_to_werror(status);
3723 if (!NT_STATUS_IS_OK(result)) {
3724 werr = ntstatus_to_werror(result);
3727 if (names.count != num_rids) {
3728 werr = WERR_BAD_NET_RESP;
3731 if (types.count != num_rids) {
3732 werr = WERR_BAD_NET_RESP;
3736 for (i=0; i < names.count; i++) {
3737 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3739 names.names[i].string,
3742 if (!NT_STATUS_IS_OK(status)) {
3743 werr = ntstatus_to_werror(status);
3748 *r->out.entries_read = entries_read;
3749 *r->out.total_entries = entries_read;
3752 if (ctx->disable_policy_handle_cache) {
3753 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3754 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3760 /****************************************************************
3761 ****************************************************************/
3763 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3764 struct NetUserGetLocalGroups *r)
3766 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);