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/cli_samr.h"
27 #include "rpc_client/init_samr.h"
28 #include "../libds/common/flags.h"
30 /****************************************************************
31 ****************************************************************/
33 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
34 struct samr_UserInfo21 *info21)
36 uint32_t fields_present = 0;
37 struct samr_LogonHours zero_logon_hours;
38 struct lsa_BinaryString zero_parameters;
42 ZERO_STRUCT(zero_logon_hours);
43 ZERO_STRUCT(zero_parameters);
45 if (infoX->usriX_flags) {
46 fields_present |= SAMR_FIELD_ACCT_FLAGS;
48 if (infoX->usriX_name) {
49 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
51 if (infoX->usriX_password) {
52 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
54 if (infoX->usriX_flags) {
55 fields_present |= SAMR_FIELD_ACCT_FLAGS;
57 if (infoX->usriX_name) {
58 fields_present |= SAMR_FIELD_FULL_NAME;
60 if (infoX->usriX_home_dir) {
61 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
63 if (infoX->usriX_script_path) {
64 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
66 if (infoX->usriX_comment) {
67 fields_present |= SAMR_FIELD_DESCRIPTION;
69 if (infoX->usriX_password_age) {
70 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
72 if (infoX->usriX_full_name) {
73 fields_present |= SAMR_FIELD_FULL_NAME;
75 if (infoX->usriX_usr_comment) {
76 fields_present |= SAMR_FIELD_COMMENT;
78 if (infoX->usriX_profile) {
79 fields_present |= SAMR_FIELD_PROFILE_PATH;
81 if (infoX->usriX_home_dir_drive) {
82 fields_present |= SAMR_FIELD_HOME_DRIVE;
84 if (infoX->usriX_primary_group_id) {
85 fields_present |= SAMR_FIELD_PRIMARY_GID;
87 if (infoX->usriX_country_code) {
88 fields_present |= SAMR_FIELD_COUNTRY_CODE;
90 if (infoX->usriX_workstations) {
91 fields_present |= SAMR_FIELD_WORKSTATIONS;
94 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
96 /* TODO: infoX->usriX_priv */
98 info21->last_logon = 0;
99 info21->last_logoff = 0;
100 info21->last_password_change = 0;
101 info21->acct_expiry = 0;
102 info21->allow_password_change = 0;
103 info21->force_password_change = 0;
104 info21->account_name.string = infoX->usriX_name;
105 info21->full_name.string = infoX->usriX_full_name;
106 info21->home_directory.string = infoX->usriX_home_dir;
107 info21->home_drive.string = infoX->usriX_home_dir_drive;
108 info21->logon_script.string = infoX->usriX_script_path;
109 info21->profile_path.string = infoX->usriX_profile;
110 info21->description.string = infoX->usriX_comment;
111 info21->workstations.string = infoX->usriX_workstations;
112 info21->comment.string = infoX->usriX_usr_comment;
113 info21->parameters = zero_parameters;
114 info21->lm_owf_password = zero_parameters;
115 info21->nt_owf_password = zero_parameters;
116 info21->unknown3.string = NULL;
117 info21->buf_count = 0;
118 info21->buffer = NULL;
119 info21->rid = infoX->usriX_user_id;
120 info21->primary_gid = infoX->usriX_primary_group_id;
121 info21->acct_flags = infoX->usriX_flags;
122 info21->fields_present = fields_present;
123 info21->logon_hours = zero_logon_hours;
124 info21->bad_password_count = infoX->usriX_bad_pw_count;
125 info21->logon_count = infoX->usriX_num_logons;
126 info21->country_code = infoX->usriX_country_code;
127 info21->code_page = infoX->usriX_code_page;
128 info21->lm_password_set = 0;
129 info21->nt_password_set = 0;
130 info21->password_expired = infoX->usriX_password_expired;
131 info21->unknown4 = 0;
134 /****************************************************************
135 ****************************************************************/
137 static NTSTATUS construct_USER_INFO_X(uint32_t level,
139 struct USER_INFO_X *uX)
141 struct USER_INFO_0 *u0 = NULL;
142 struct USER_INFO_1 *u1 = NULL;
143 struct USER_INFO_2 *u2 = NULL;
144 struct USER_INFO_3 *u3 = NULL;
145 struct USER_INFO_1003 *u1003 = NULL;
146 struct USER_INFO_1006 *u1006 = NULL;
147 struct USER_INFO_1007 *u1007 = NULL;
148 struct USER_INFO_1009 *u1009 = NULL;
149 struct USER_INFO_1011 *u1011 = NULL;
150 struct USER_INFO_1012 *u1012 = NULL;
151 struct USER_INFO_1014 *u1014 = NULL;
152 struct USER_INFO_1024 *u1024 = NULL;
153 struct USER_INFO_1051 *u1051 = NULL;
154 struct USER_INFO_1052 *u1052 = NULL;
155 struct USER_INFO_1053 *u1053 = NULL;
157 if (!buffer || !uX) {
158 return NT_STATUS_INVALID_PARAMETER;
165 u0 = (struct USER_INFO_0 *)buffer;
166 uX->usriX_name = u0->usri0_name;
169 u1 = (struct USER_INFO_1 *)buffer;
170 uX->usriX_name = u1->usri1_name;
171 uX->usriX_password = u1->usri1_password;
172 uX->usriX_password_age = u1->usri1_password_age;
173 uX->usriX_priv = u1->usri1_priv;
174 uX->usriX_home_dir = u1->usri1_home_dir;
175 uX->usriX_comment = u1->usri1_comment;
176 uX->usriX_flags = u1->usri1_flags;
177 uX->usriX_script_path = u1->usri1_script_path;
180 u2 = (struct USER_INFO_2 *)buffer;
181 uX->usriX_name = u2->usri2_name;
182 uX->usriX_password = u2->usri2_password;
183 uX->usriX_password_age = u2->usri2_password_age;
184 uX->usriX_priv = u2->usri2_priv;
185 uX->usriX_home_dir = u2->usri2_home_dir;
186 uX->usriX_comment = u2->usri2_comment;
187 uX->usriX_flags = u2->usri2_flags;
188 uX->usriX_script_path = u2->usri2_script_path;
189 uX->usriX_auth_flags = u2->usri2_auth_flags;
190 uX->usriX_full_name = u2->usri2_full_name;
191 uX->usriX_usr_comment = u2->usri2_usr_comment;
192 uX->usriX_parms = u2->usri2_parms;
193 uX->usriX_workstations = u2->usri2_workstations;
194 uX->usriX_last_logon = u2->usri2_last_logon;
195 uX->usriX_last_logoff = u2->usri2_last_logoff;
196 uX->usriX_acct_expires = u2->usri2_acct_expires;
197 uX->usriX_max_storage = u2->usri2_max_storage;
198 uX->usriX_units_per_week= u2->usri2_units_per_week;
199 uX->usriX_logon_hours = u2->usri2_logon_hours;
200 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
201 uX->usriX_num_logons = u2->usri2_num_logons;
202 uX->usriX_logon_server = u2->usri2_logon_server;
203 uX->usriX_country_code = u2->usri2_country_code;
204 uX->usriX_code_page = u2->usri2_code_page;
207 u3 = (struct USER_INFO_3 *)buffer;
208 uX->usriX_name = u3->usri3_name;
209 uX->usriX_password_age = u3->usri3_password_age;
210 uX->usriX_priv = u3->usri3_priv;
211 uX->usriX_home_dir = u3->usri3_home_dir;
212 uX->usriX_comment = u3->usri3_comment;
213 uX->usriX_flags = u3->usri3_flags;
214 uX->usriX_script_path = u3->usri3_script_path;
215 uX->usriX_auth_flags = u3->usri3_auth_flags;
216 uX->usriX_full_name = u3->usri3_full_name;
217 uX->usriX_usr_comment = u3->usri3_usr_comment;
218 uX->usriX_parms = u3->usri3_parms;
219 uX->usriX_workstations = u3->usri3_workstations;
220 uX->usriX_last_logon = u3->usri3_last_logon;
221 uX->usriX_last_logoff = u3->usri3_last_logoff;
222 uX->usriX_acct_expires = u3->usri3_acct_expires;
223 uX->usriX_max_storage = u3->usri3_max_storage;
224 uX->usriX_units_per_week= u3->usri3_units_per_week;
225 uX->usriX_logon_hours = u3->usri3_logon_hours;
226 uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
227 uX->usriX_num_logons = u3->usri3_num_logons;
228 uX->usriX_logon_server = u3->usri3_logon_server;
229 uX->usriX_country_code = u3->usri3_country_code;
230 uX->usriX_code_page = u3->usri3_code_page;
231 uX->usriX_user_id = u3->usri3_user_id;
232 uX->usriX_primary_group_id = u3->usri3_primary_group_id;
233 uX->usriX_profile = u3->usri3_profile;
234 uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
235 uX->usriX_password_expired = u3->usri3_password_expired;
238 u1003 = (struct USER_INFO_1003 *)buffer;
239 uX->usriX_password = u1003->usri1003_password;
242 u1006 = (struct USER_INFO_1006 *)buffer;
243 uX->usriX_home_dir = u1006->usri1006_home_dir;
246 u1007 = (struct USER_INFO_1007 *)buffer;
247 uX->usriX_comment = u1007->usri1007_comment;
250 u1009 = (struct USER_INFO_1009 *)buffer;
251 uX->usriX_script_path = u1009->usri1009_script_path;
254 u1011 = (struct USER_INFO_1011 *)buffer;
255 uX->usriX_full_name = u1011->usri1011_full_name;
258 u1012 = (struct USER_INFO_1012 *)buffer;
259 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
262 u1014 = (struct USER_INFO_1014 *)buffer;
263 uX->usriX_workstations = u1014->usri1014_workstations;
266 u1024 = (struct USER_INFO_1024 *)buffer;
267 uX->usriX_country_code = u1024->usri1024_country_code;
270 u1051 = (struct USER_INFO_1051 *)buffer;
271 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
274 u1052 = (struct USER_INFO_1052 *)buffer;
275 uX->usriX_profile = u1052->usri1052_profile;
278 u1053 = (struct USER_INFO_1053 *)buffer;
279 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
283 return NT_STATUS_INVALID_INFO_CLASS;
289 /****************************************************************
290 ****************************************************************/
292 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
293 struct rpc_pipe_client *pipe_cli,
294 DATA_BLOB *session_key,
295 struct policy_handle *user_handle,
296 struct USER_INFO_X *uX)
298 union samr_UserInfo user_info;
299 struct samr_UserInfo21 info21;
303 return NT_STATUS_INVALID_PARAMETER;
306 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
308 ZERO_STRUCT(user_info);
310 if (uX->usriX_password) {
312 user_info.info25.info = info21;
314 init_samr_CryptPasswordEx(uX->usriX_password,
316 &user_info.info25.password);
318 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
323 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
325 user_info.info23.info = info21;
327 init_samr_CryptPassword(uX->usriX_password,
329 &user_info.info23.password);
331 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
338 user_info.info21 = info21;
340 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
349 /****************************************************************
350 ****************************************************************/
352 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
353 struct NetUserAdd *r)
355 struct rpc_pipe_client *pipe_cli = NULL;
358 struct policy_handle connect_handle, domain_handle, user_handle;
359 struct lsa_String lsa_account_name;
360 struct dom_sid2 *domain_sid = NULL;
361 union samr_UserInfo *user_info = NULL;
362 struct samr_PwInfo pw_info;
363 uint32_t access_granted = 0;
365 struct USER_INFO_X uX;
367 ZERO_STRUCT(connect_handle);
368 ZERO_STRUCT(domain_handle);
369 ZERO_STRUCT(user_handle);
372 return WERR_INVALID_PARAM;
375 switch (r->in.level) {
382 werr = WERR_NOT_SUPPORTED;
386 werr = libnetapi_open_pipe(ctx, r->in.server_name,
387 &ndr_table_samr.syntax_id,
389 if (!W_ERROR_IS_OK(werr)) {
393 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
394 if (!NT_STATUS_IS_OK(status)) {
395 werr = ntstatus_to_werror(status);
399 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
400 SAMR_ACCESS_ENUM_DOMAINS |
401 SAMR_ACCESS_LOOKUP_DOMAIN,
402 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
403 SAMR_DOMAIN_ACCESS_CREATE_USER |
404 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
408 if (!W_ERROR_IS_OK(werr)) {
412 init_lsa_String(&lsa_account_name, uX.usriX_name);
414 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
420 SAMR_USER_ACCESS_SET_PASSWORD |
421 SAMR_USER_ACCESS_SET_ATTRIBUTES |
422 SAMR_USER_ACCESS_GET_ATTRIBUTES,
426 if (!NT_STATUS_IS_OK(status)) {
427 werr = ntstatus_to_werror(status);
431 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
435 if (!NT_STATUS_IS_OK(status)) {
436 werr = ntstatus_to_werror(status);
440 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
441 werr = WERR_INVALID_PARAM;
445 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
448 if (!NT_STATUS_IS_OK(status)) {
449 werr = ntstatus_to_werror(status);
453 uX.usriX_flags |= ACB_NORMAL;
455 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
456 &pipe_cli->auth->user_session_key,
459 if (!NT_STATUS_IS_OK(status)) {
460 werr = ntstatus_to_werror(status);
468 rpccli_samr_DeleteUser(pipe_cli, ctx,
472 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
473 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
476 if (ctx->disable_policy_handle_cache) {
477 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
478 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
484 /****************************************************************
485 ****************************************************************/
487 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
488 struct NetUserAdd *r)
490 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
493 /****************************************************************
494 ****************************************************************/
496 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
497 struct NetUserDel *r)
499 struct rpc_pipe_client *pipe_cli = NULL;
502 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
503 struct lsa_String lsa_account_name;
504 struct samr_Ids user_rids, name_types;
505 struct dom_sid2 *domain_sid = NULL;
506 struct dom_sid2 user_sid;
508 ZERO_STRUCT(connect_handle);
509 ZERO_STRUCT(builtin_handle);
510 ZERO_STRUCT(domain_handle);
511 ZERO_STRUCT(user_handle);
513 werr = libnetapi_open_pipe(ctx, r->in.server_name,
514 &ndr_table_samr.syntax_id,
517 if (!W_ERROR_IS_OK(werr)) {
521 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
522 SAMR_ACCESS_ENUM_DOMAINS |
523 SAMR_ACCESS_LOOKUP_DOMAIN,
524 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
528 if (!W_ERROR_IS_OK(werr)) {
532 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
534 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
535 CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
537 if (!NT_STATUS_IS_OK(status)) {
538 werr = ntstatus_to_werror(status);
542 init_lsa_String(&lsa_account_name, r->in.user_name);
544 status = rpccli_samr_LookupNames(pipe_cli, ctx,
550 if (!NT_STATUS_IS_OK(status)) {
551 werr = ntstatus_to_werror(status);
555 status = rpccli_samr_OpenUser(pipe_cli, ctx,
560 if (!NT_STATUS_IS_OK(status)) {
561 werr = ntstatus_to_werror(status);
565 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
567 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
570 if (!NT_STATUS_IS_OK(status)) {
571 werr = ntstatus_to_werror(status);
575 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
577 if (!NT_STATUS_IS_OK(status)) {
578 werr = ntstatus_to_werror(status);
585 if (is_valid_policy_hnd(&user_handle)) {
586 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
589 if (ctx->disable_policy_handle_cache) {
590 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
591 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
592 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
598 /****************************************************************
599 ****************************************************************/
601 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
602 struct NetUserDel *r)
604 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
607 /****************************************************************
608 ****************************************************************/
610 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
611 struct rpc_pipe_client *pipe_cli,
612 struct policy_handle *domain_handle,
613 struct policy_handle *builtin_handle,
614 const char *user_name,
615 const struct dom_sid *domain_sid,
618 struct samr_UserInfo21 **info21,
619 struct sec_desc_buf **sec_desc,
620 uint32_t *auth_flag_p)
624 struct policy_handle user_handle;
625 union samr_UserInfo *user_info = NULL;
626 struct samr_RidWithAttributeArray *rid_array = NULL;
627 uint32_t access_mask = SEC_STD_READ_CONTROL |
628 SAMR_USER_ACCESS_GET_ATTRIBUTES |
629 SAMR_USER_ACCESS_GET_NAME_ETC;
631 ZERO_STRUCT(user_handle);
637 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
638 SAMR_USER_ACCESS_GET_GROUPS;
644 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
645 SAMR_USER_ACCESS_GET_GROUPS |
646 SAMR_USER_ACCESS_GET_LOCALE;
653 return NT_STATUS_INVALID_LEVEL;
660 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
665 if (!NT_STATUS_IS_OK(status)) {
669 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
673 if (!NT_STATUS_IS_OK(status)) {
677 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
681 if (!NT_STATUS_IS_OK(status)) {
685 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
687 struct lsa_SidArray sid_array;
688 struct samr_Ids alias_rids;
690 uint32_t auth_flag = 0;
693 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
696 if (!NT_STATUS_IS_OK(status)) {
700 sid_array.num_sids = rid_array->count + 1;
701 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
703 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
705 for (i=0; i<rid_array->count; i++) {
706 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
707 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
708 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
711 sid_compose(&sid, domain_sid, rid);
712 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
713 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
715 status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
719 if (!NT_STATUS_IS_OK(status)) {
723 for (i=0; i<alias_rids.count; i++) {
724 switch (alias_rids.ids[i]) {
725 case 550: /* Print Operators */
726 auth_flag |= AF_OP_PRINT;
728 case 549: /* Server Operators */
729 auth_flag |= AF_OP_SERVER;
731 case 548: /* Account Operators */
732 auth_flag |= AF_OP_ACCOUNTS;
740 *auth_flag_p = auth_flag;
744 *info21 = &user_info->info21;
747 if (is_valid_policy_hnd(&user_handle)) {
748 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
754 /****************************************************************
755 ****************************************************************/
757 static uint32_t samr_rid_to_priv_level(uint32_t rid)
760 case DOMAIN_RID_ADMINISTRATOR:
761 return USER_PRIV_ADMIN;
762 case DOMAIN_RID_GUEST:
763 return USER_PRIV_GUEST;
765 return USER_PRIV_USER;
769 /****************************************************************
770 ****************************************************************/
772 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
774 uint32_t fl = UF_SCRIPT; /* god knows why */
776 fl |= ds_acb2uf(acb);
781 /****************************************************************
782 ****************************************************************/
784 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
785 const struct samr_UserInfo21 *i21,
786 struct USER_INFO_1 *i)
789 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
790 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
791 i->usri1_password = NULL;
792 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
793 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
794 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
795 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
796 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
797 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
802 /****************************************************************
803 ****************************************************************/
805 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
806 const struct samr_UserInfo21 *i21,
808 struct USER_INFO_2 *i)
812 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
813 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
814 i->usri2_password = NULL;
815 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
816 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
817 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
818 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
819 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
820 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
821 i->usri2_auth_flags = auth_flag;
822 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
823 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
824 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
825 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
826 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
827 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
828 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
829 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
830 i->usri2_units_per_week = i21->logon_hours.units_per_week;
831 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
832 i->usri2_bad_pw_count = i21->bad_password_count;
833 i->usri2_num_logons = i21->logon_count;
834 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
835 i->usri2_country_code = i21->country_code;
836 i->usri2_code_page = i21->code_page;
841 /****************************************************************
842 ****************************************************************/
844 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
845 const struct samr_UserInfo21 *i21,
847 struct USER_INFO_3 *i)
851 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
852 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
853 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
854 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
855 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
856 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
857 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
858 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
859 i->usri3_auth_flags = auth_flag;
860 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
861 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
862 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
863 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
864 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
865 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
866 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
867 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
868 i->usri3_units_per_week = i21->logon_hours.units_per_week;
869 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
870 i->usri3_bad_pw_count = i21->bad_password_count;
871 i->usri3_num_logons = i21->logon_count;
872 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
873 i->usri3_country_code = i21->country_code;
874 i->usri3_code_page = i21->code_page;
875 i->usri3_user_id = i21->rid;
876 i->usri3_primary_group_id = i21->primary_gid;
877 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
878 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
879 i->usri3_password_expired = i21->password_expired;
884 /****************************************************************
885 ****************************************************************/
887 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
888 const struct samr_UserInfo21 *i21,
890 struct dom_sid *domain_sid,
891 struct USER_INFO_4 *i)
897 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
898 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
899 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
900 i->usri4_password = NULL;
901 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
902 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
903 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
904 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
905 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
906 i->usri4_auth_flags = auth_flag;
907 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
908 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
909 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
910 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
911 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
912 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
913 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
914 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
915 i->usri4_units_per_week = i21->logon_hours.units_per_week;
916 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
917 i->usri4_bad_pw_count = i21->bad_password_count;
918 i->usri4_num_logons = i21->logon_count;
919 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
920 i->usri4_country_code = i21->country_code;
921 i->usri4_code_page = i21->code_page;
922 if (!sid_compose(&sid, domain_sid, i21->rid)) {
923 return NT_STATUS_NO_MEMORY;
925 i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
926 i->usri4_primary_group_id = i21->primary_gid;
927 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
928 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
929 i->usri4_password_expired = i21->password_expired;
934 /****************************************************************
935 ****************************************************************/
937 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
938 const struct samr_UserInfo21 *i21,
939 struct USER_INFO_10 *i)
943 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
944 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
945 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
946 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
947 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
952 /****************************************************************
953 ****************************************************************/
955 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
956 const struct samr_UserInfo21 *i21,
958 struct USER_INFO_11 *i)
962 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
963 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
964 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
965 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
966 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
967 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
968 i->usri11_auth_flags = auth_flag;
969 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
970 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
971 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
972 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
973 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
974 i->usri11_bad_pw_count = i21->bad_password_count;
975 i->usri11_num_logons = i21->logon_count;
976 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
977 i->usri11_country_code = i21->country_code;
978 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
979 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
980 i->usri11_units_per_week = i21->logon_hours.units_per_week;
981 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
982 i->usri11_code_page = i21->code_page;
987 /****************************************************************
988 ****************************************************************/
990 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
991 const struct samr_UserInfo21 *i21,
992 struct USER_INFO_20 *i)
996 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
997 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
998 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
999 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1000 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1001 i->usri20_user_id = i21->rid;
1003 return NT_STATUS_OK;
1006 /****************************************************************
1007 ****************************************************************/
1009 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1010 const struct samr_UserInfo21 *i21,
1011 struct dom_sid *domain_sid,
1012 struct USER_INFO_23 *i)
1018 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1019 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1020 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1021 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1022 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1023 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1024 return NT_STATUS_NO_MEMORY;
1026 i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
1028 return NT_STATUS_OK;
1031 /****************************************************************
1032 ****************************************************************/
1034 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1035 struct rpc_pipe_client *pipe_cli,
1036 struct dom_sid *domain_sid,
1037 struct policy_handle *domain_handle,
1038 struct policy_handle *builtin_handle,
1039 const char *user_name,
1043 uint32_t *num_entries)
1047 struct samr_UserInfo21 *info21 = NULL;
1048 struct sec_desc_buf *sec_desc = NULL;
1049 uint32_t auth_flag = 0;
1051 struct USER_INFO_0 info0;
1052 struct USER_INFO_1 info1;
1053 struct USER_INFO_2 info2;
1054 struct USER_INFO_3 info3;
1055 struct USER_INFO_4 info4;
1056 struct USER_INFO_10 info10;
1057 struct USER_INFO_11 info11;
1058 struct USER_INFO_20 info20;
1059 struct USER_INFO_23 info23;
1073 return NT_STATUS_INVALID_LEVEL;
1077 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1078 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1080 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1081 (struct USER_INFO_0 **)buffer, num_entries);
1083 return NT_STATUS_OK;
1086 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1097 if (!NT_STATUS_IS_OK(status)) {
1103 /* already returned above */
1106 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1107 NT_STATUS_NOT_OK_RETURN(status);
1109 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1110 (struct USER_INFO_1 **)buffer, num_entries);
1114 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1115 NT_STATUS_NOT_OK_RETURN(status);
1117 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1118 (struct USER_INFO_2 **)buffer, num_entries);
1122 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1123 NT_STATUS_NOT_OK_RETURN(status);
1125 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1126 (struct USER_INFO_3 **)buffer, num_entries);
1130 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1131 NT_STATUS_NOT_OK_RETURN(status);
1133 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1134 (struct USER_INFO_4 **)buffer, num_entries);
1138 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1139 NT_STATUS_NOT_OK_RETURN(status);
1141 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1142 (struct USER_INFO_10 **)buffer, num_entries);
1146 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1147 NT_STATUS_NOT_OK_RETURN(status);
1149 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1150 (struct USER_INFO_11 **)buffer, num_entries);
1154 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1155 NT_STATUS_NOT_OK_RETURN(status);
1157 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1158 (struct USER_INFO_20 **)buffer, num_entries);
1162 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1163 NT_STATUS_NOT_OK_RETURN(status);
1165 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1166 (struct USER_INFO_23 **)buffer, num_entries);
1169 return NT_STATUS_INVALID_LEVEL;
1176 /****************************************************************
1177 ****************************************************************/
1179 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1180 struct NetUserEnum *r)
1182 struct rpc_pipe_client *pipe_cli = NULL;
1183 struct policy_handle connect_handle;
1184 struct dom_sid2 *domain_sid = NULL;
1185 struct policy_handle domain_handle, builtin_handle;
1186 struct samr_SamArray *sam = NULL;
1187 uint32_t filter = ACB_NORMAL;
1189 uint32_t entries_read = 0;
1191 NTSTATUS status = NT_STATUS_OK;
1194 ZERO_STRUCT(connect_handle);
1195 ZERO_STRUCT(domain_handle);
1196 ZERO_STRUCT(builtin_handle);
1198 if (!r->out.buffer) {
1199 return WERR_INVALID_PARAM;
1202 *r->out.buffer = NULL;
1203 *r->out.entries_read = 0;
1205 switch (r->in.level) {
1217 return WERR_UNKNOWN_LEVEL;
1220 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1221 &ndr_table_samr.syntax_id,
1223 if (!W_ERROR_IS_OK(werr)) {
1227 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1228 SAMR_ACCESS_ENUM_DOMAINS |
1229 SAMR_ACCESS_LOOKUP_DOMAIN,
1230 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1231 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1234 if (!W_ERROR_IS_OK(werr)) {
1238 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1239 SAMR_ACCESS_ENUM_DOMAINS |
1240 SAMR_ACCESS_LOOKUP_DOMAIN,
1241 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1242 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1243 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1247 if (!W_ERROR_IS_OK(werr)) {
1251 switch (r->in.filter) {
1252 case FILTER_NORMAL_ACCOUNT:
1253 filter = ACB_NORMAL;
1255 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1256 filter = ACB_TEMPDUP;
1258 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1259 filter = ACB_DOMTRUST;
1261 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1262 filter = ACB_WSTRUST;
1264 case FILTER_SERVER_TRUST_ACCOUNT:
1265 filter = ACB_SVRTRUST;
1271 status = rpccli_samr_EnumDomainUsers(pipe_cli,
1274 r->in.resume_handle,
1279 werr = ntstatus_to_werror(status);
1280 if (NT_STATUS_IS_ERR(status)) {
1284 for (i=0; i < sam->count; i++) {
1286 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1290 sam->entries[i].name.string,
1291 sam->entries[i].idx,
1294 r->out.entries_read);
1295 if (!NT_STATUS_IS_OK(status)) {
1296 werr = ntstatus_to_werror(status);
1303 if (NT_STATUS_IS_OK(status) ||
1304 NT_STATUS_IS_ERR(status)) {
1306 if (ctx->disable_policy_handle_cache) {
1307 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1308 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1309 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1316 /****************************************************************
1317 ****************************************************************/
1319 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1320 struct NetUserEnum *r)
1322 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1325 /****************************************************************
1326 ****************************************************************/
1328 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1329 struct samr_DispInfoGeneral *info,
1330 uint32_t *entries_read,
1333 struct NET_DISPLAY_USER *user = NULL;
1336 user = TALLOC_ZERO_ARRAY(mem_ctx,
1337 struct NET_DISPLAY_USER,
1339 W_ERROR_HAVE_NO_MEMORY(user);
1341 for (i = 0; i < info->count; i++) {
1342 user[i].usri1_name = talloc_strdup(mem_ctx,
1343 info->entries[i].account_name.string);
1344 user[i].usri1_comment = talloc_strdup(mem_ctx,
1345 info->entries[i].description.string);
1346 user[i].usri1_flags =
1347 info->entries[i].acct_flags;
1348 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1349 info->entries[i].full_name.string);
1350 user[i].usri1_user_id =
1351 info->entries[i].rid;
1352 user[i].usri1_next_index =
1353 info->entries[i].idx;
1355 if (!user[i].usri1_name) {
1360 *buffer = talloc_memdup(mem_ctx, user,
1361 sizeof(struct NET_DISPLAY_USER) * info->count);
1362 W_ERROR_HAVE_NO_MEMORY(*buffer);
1364 *entries_read = info->count;
1369 /****************************************************************
1370 ****************************************************************/
1372 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1373 struct samr_DispInfoFull *info,
1374 uint32_t *entries_read,
1377 struct NET_DISPLAY_MACHINE *machine = NULL;
1380 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1381 struct NET_DISPLAY_MACHINE,
1383 W_ERROR_HAVE_NO_MEMORY(machine);
1385 for (i = 0; i < info->count; i++) {
1386 machine[i].usri2_name = talloc_strdup(mem_ctx,
1387 info->entries[i].account_name.string);
1388 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1389 info->entries[i].description.string);
1390 machine[i].usri2_flags =
1391 info->entries[i].acct_flags;
1392 machine[i].usri2_user_id =
1393 info->entries[i].rid;
1394 machine[i].usri2_next_index =
1395 info->entries[i].idx;
1397 if (!machine[i].usri2_name) {
1402 *buffer = talloc_memdup(mem_ctx, machine,
1403 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1404 W_ERROR_HAVE_NO_MEMORY(*buffer);
1406 *entries_read = info->count;
1411 /****************************************************************
1412 ****************************************************************/
1414 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1415 struct samr_DispInfoFullGroups *info,
1416 uint32_t *entries_read,
1419 struct NET_DISPLAY_GROUP *group = NULL;
1422 group = TALLOC_ZERO_ARRAY(mem_ctx,
1423 struct NET_DISPLAY_GROUP,
1425 W_ERROR_HAVE_NO_MEMORY(group);
1427 for (i = 0; i < info->count; i++) {
1428 group[i].grpi3_name = talloc_strdup(mem_ctx,
1429 info->entries[i].account_name.string);
1430 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1431 info->entries[i].description.string);
1432 group[i].grpi3_group_id =
1433 info->entries[i].rid;
1434 group[i].grpi3_attributes =
1435 info->entries[i].acct_flags;
1436 group[i].grpi3_next_index =
1437 info->entries[i].idx;
1439 if (!group[i].grpi3_name) {
1444 *buffer = talloc_memdup(mem_ctx, group,
1445 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1446 W_ERROR_HAVE_NO_MEMORY(*buffer);
1448 *entries_read = info->count;
1454 /****************************************************************
1455 ****************************************************************/
1457 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1458 union samr_DispInfo *info,
1460 uint32_t *entries_read,
1465 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1470 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1475 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1483 return WERR_UNKNOWN_LEVEL;
1486 /****************************************************************
1487 ****************************************************************/
1489 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1490 struct NetQueryDisplayInformation *r)
1492 struct rpc_pipe_client *pipe_cli = NULL;
1493 struct policy_handle connect_handle;
1494 struct dom_sid2 *domain_sid = NULL;
1495 struct policy_handle domain_handle;
1496 union samr_DispInfo info;
1498 uint32_t total_size = 0;
1499 uint32_t returned_size = 0;
1501 NTSTATUS status = NT_STATUS_OK;
1505 *r->out.entries_read = 0;
1507 ZERO_STRUCT(connect_handle);
1508 ZERO_STRUCT(domain_handle);
1510 switch (r->in.level) {
1516 return WERR_UNKNOWN_LEVEL;
1519 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1520 &ndr_table_samr.syntax_id,
1522 if (!W_ERROR_IS_OK(werr)) {
1526 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1527 SAMR_ACCESS_ENUM_DOMAINS |
1528 SAMR_ACCESS_LOOKUP_DOMAIN,
1529 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1530 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1531 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1535 if (!W_ERROR_IS_OK(werr)) {
1539 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1544 r->in.entries_requested,
1549 werr = ntstatus_to_werror(status);
1550 if (NT_STATUS_IS_ERR(status)) {
1554 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1556 r->out.entries_read,
1558 if (!W_ERROR_IS_OK(werr_tmp)) {
1563 if (NT_STATUS_IS_OK(status) ||
1564 NT_STATUS_IS_ERR(status)) {
1566 if (ctx->disable_policy_handle_cache) {
1567 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1568 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1576 /****************************************************************
1577 ****************************************************************/
1580 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1581 struct NetQueryDisplayInformation *r)
1583 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1586 /****************************************************************
1587 ****************************************************************/
1589 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1590 struct NetUserChangePassword *r)
1592 return WERR_NOT_SUPPORTED;
1595 /****************************************************************
1596 ****************************************************************/
1598 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1599 struct NetUserChangePassword *r)
1601 return WERR_NOT_SUPPORTED;
1604 /****************************************************************
1605 ****************************************************************/
1607 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1608 struct NetUserGetInfo *r)
1610 struct rpc_pipe_client *pipe_cli = NULL;
1614 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1615 struct lsa_String lsa_account_name;
1616 struct dom_sid2 *domain_sid = NULL;
1617 struct samr_Ids user_rids, name_types;
1618 uint32_t num_entries = 0;
1620 ZERO_STRUCT(connect_handle);
1621 ZERO_STRUCT(domain_handle);
1622 ZERO_STRUCT(builtin_handle);
1623 ZERO_STRUCT(user_handle);
1625 if (!r->out.buffer) {
1626 return WERR_INVALID_PARAM;
1629 switch (r->in.level) {
1641 werr = WERR_UNKNOWN_LEVEL;
1645 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1646 &ndr_table_samr.syntax_id,
1648 if (!W_ERROR_IS_OK(werr)) {
1652 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1653 SAMR_ACCESS_ENUM_DOMAINS |
1654 SAMR_ACCESS_LOOKUP_DOMAIN,
1655 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1659 if (!W_ERROR_IS_OK(werr)) {
1663 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1664 SAMR_ACCESS_ENUM_DOMAINS |
1665 SAMR_ACCESS_LOOKUP_DOMAIN,
1666 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1667 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1670 if (!W_ERROR_IS_OK(werr)) {
1674 init_lsa_String(&lsa_account_name, r->in.user_name);
1676 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1682 if (!NT_STATUS_IS_OK(status)) {
1683 werr = ntstatus_to_werror(status);
1687 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1696 if (!NT_STATUS_IS_OK(status)) {
1697 werr = ntstatus_to_werror(status);
1702 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1703 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1706 if (ctx->disable_policy_handle_cache) {
1707 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1708 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1714 /****************************************************************
1715 ****************************************************************/
1717 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1718 struct NetUserGetInfo *r)
1720 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1723 /****************************************************************
1724 ****************************************************************/
1726 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1727 struct NetUserSetInfo *r)
1729 struct rpc_pipe_client *pipe_cli = NULL;
1733 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1734 struct lsa_String lsa_account_name;
1735 struct dom_sid2 *domain_sid = NULL;
1736 struct samr_Ids user_rids, name_types;
1737 uint32_t user_mask = 0;
1739 struct USER_INFO_X uX;
1741 ZERO_STRUCT(connect_handle);
1742 ZERO_STRUCT(domain_handle);
1743 ZERO_STRUCT(builtin_handle);
1744 ZERO_STRUCT(user_handle);
1746 if (!r->in.buffer) {
1747 return WERR_INVALID_PARAM;
1750 switch (r->in.level) {
1752 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1755 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1764 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1768 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1770 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1771 SAMR_USER_ACCESS_GET_GROUPS;
1774 user_mask = SEC_STD_READ_CONTROL |
1776 SAMR_USER_ACCESS_GET_GROUPS |
1777 SAMR_USER_ACCESS_SET_PASSWORD |
1778 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1779 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1780 SAMR_USER_ACCESS_SET_LOC_COM;
1792 werr = WERR_NOT_SUPPORTED;
1795 werr = WERR_UNKNOWN_LEVEL;
1799 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1800 &ndr_table_samr.syntax_id,
1802 if (!W_ERROR_IS_OK(werr)) {
1806 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1807 SAMR_ACCESS_ENUM_DOMAINS |
1808 SAMR_ACCESS_LOOKUP_DOMAIN,
1809 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1810 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1814 if (!W_ERROR_IS_OK(werr)) {
1818 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1819 SAMR_ACCESS_ENUM_DOMAINS |
1820 SAMR_ACCESS_LOOKUP_DOMAIN,
1821 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1822 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1825 if (!W_ERROR_IS_OK(werr)) {
1829 init_lsa_String(&lsa_account_name, r->in.user_name);
1831 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1837 if (!NT_STATUS_IS_OK(status)) {
1838 werr = ntstatus_to_werror(status);
1842 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1847 if (!NT_STATUS_IS_OK(status)) {
1848 werr = ntstatus_to_werror(status);
1852 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 werr = ntstatus_to_werror(status);
1858 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1859 &pipe_cli->auth->user_session_key,
1862 if (!NT_STATUS_IS_OK(status)) {
1863 werr = ntstatus_to_werror(status);
1870 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1871 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1874 if (ctx->disable_policy_handle_cache) {
1875 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1876 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1877 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1883 /****************************************************************
1884 ****************************************************************/
1886 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1887 struct NetUserSetInfo *r)
1889 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1892 /****************************************************************
1893 ****************************************************************/
1895 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1896 struct rpc_pipe_client *pipe_cli,
1897 struct policy_handle *domain_handle,
1898 struct samr_DomInfo1 *info1,
1899 struct samr_DomInfo3 *info3,
1900 struct samr_DomInfo5 *info5,
1901 struct samr_DomInfo6 *info6,
1902 struct samr_DomInfo7 *info7,
1903 struct samr_DomInfo12 *info12)
1906 union samr_DomainInfo *dom_info = NULL;
1909 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1913 NT_STATUS_NOT_OK_RETURN(status);
1915 *info1 = dom_info->info1;
1919 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1923 NT_STATUS_NOT_OK_RETURN(status);
1925 *info3 = dom_info->info3;
1929 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1933 NT_STATUS_NOT_OK_RETURN(status);
1935 *info5 = dom_info->info5;
1939 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1943 NT_STATUS_NOT_OK_RETURN(status);
1945 *info6 = dom_info->info6;
1949 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1953 NT_STATUS_NOT_OK_RETURN(status);
1955 *info7 = dom_info->info7;
1959 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1963 NT_STATUS_NOT_OK_RETURN(status);
1965 *info12 = dom_info->info12;
1968 return NT_STATUS_OK;
1971 /****************************************************************
1972 ****************************************************************/
1974 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1975 struct rpc_pipe_client *pipe_cli,
1976 struct policy_handle *domain_handle,
1977 struct USER_MODALS_INFO_0 *info0)
1980 struct samr_DomInfo1 dom_info1;
1981 struct samr_DomInfo3 dom_info3;
1983 ZERO_STRUCTP(info0);
1985 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1994 NT_STATUS_NOT_OK_RETURN(status);
1996 info0->usrmod0_min_passwd_len =
1997 dom_info1.min_password_length;
1998 info0->usrmod0_max_passwd_age =
1999 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2000 info0->usrmod0_min_passwd_age =
2001 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2002 info0->usrmod0_password_hist_len =
2003 dom_info1.password_history_length;
2005 info0->usrmod0_force_logoff =
2006 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2008 return NT_STATUS_OK;
2011 /****************************************************************
2012 ****************************************************************/
2014 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2015 struct rpc_pipe_client *pipe_cli,
2016 struct policy_handle *domain_handle,
2017 struct USER_MODALS_INFO_1 *info1)
2020 struct samr_DomInfo6 dom_info6;
2021 struct samr_DomInfo7 dom_info7;
2023 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2032 NT_STATUS_NOT_OK_RETURN(status);
2034 info1->usrmod1_primary =
2035 talloc_strdup(mem_ctx, dom_info6.primary.string);
2037 info1->usrmod1_role = dom_info7.role;
2039 return NT_STATUS_OK;
2042 /****************************************************************
2043 ****************************************************************/
2045 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2046 struct rpc_pipe_client *pipe_cli,
2047 struct policy_handle *domain_handle,
2048 struct dom_sid *domain_sid,
2049 struct USER_MODALS_INFO_2 *info2)
2052 struct samr_DomInfo5 dom_info5;
2054 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2063 NT_STATUS_NOT_OK_RETURN(status);
2065 info2->usrmod2_domain_name =
2066 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2067 info2->usrmod2_domain_id =
2068 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
2070 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2071 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2073 return NT_STATUS_OK;
2076 /****************************************************************
2077 ****************************************************************/
2079 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2080 struct rpc_pipe_client *pipe_cli,
2081 struct policy_handle *domain_handle,
2082 struct USER_MODALS_INFO_3 *info3)
2085 struct samr_DomInfo12 dom_info12;
2087 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2096 NT_STATUS_NOT_OK_RETURN(status);
2098 info3->usrmod3_lockout_duration =
2099 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2100 info3->usrmod3_lockout_observation_window =
2101 nt_time_to_unix_abs(&dom_info12.lockout_window);
2102 info3->usrmod3_lockout_threshold =
2103 dom_info12.lockout_threshold;
2105 return NT_STATUS_OK;
2108 /****************************************************************
2109 ****************************************************************/
2111 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2112 struct rpc_pipe_client *pipe_cli,
2114 struct policy_handle *domain_handle,
2115 struct dom_sid *domain_sid,
2120 struct USER_MODALS_INFO_0 info0;
2121 struct USER_MODALS_INFO_1 info1;
2122 struct USER_MODALS_INFO_2 info2;
2123 struct USER_MODALS_INFO_3 info3;
2126 return ERROR_INSUFFICIENT_BUFFER;
2131 status = query_USER_MODALS_INFO_0(mem_ctx,
2135 NT_STATUS_NOT_OK_RETURN(status);
2137 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2142 status = query_USER_MODALS_INFO_1(mem_ctx,
2146 NT_STATUS_NOT_OK_RETURN(status);
2148 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2152 status = query_USER_MODALS_INFO_2(mem_ctx,
2157 NT_STATUS_NOT_OK_RETURN(status);
2159 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2163 status = query_USER_MODALS_INFO_3(mem_ctx,
2167 NT_STATUS_NOT_OK_RETURN(status);
2169 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2176 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2178 return NT_STATUS_OK;
2181 /****************************************************************
2182 ****************************************************************/
2184 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2185 struct NetUserModalsGet *r)
2187 struct rpc_pipe_client *pipe_cli = NULL;
2191 struct policy_handle connect_handle, domain_handle;
2192 struct dom_sid2 *domain_sid = NULL;
2193 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2195 ZERO_STRUCT(connect_handle);
2196 ZERO_STRUCT(domain_handle);
2198 if (!r->out.buffer) {
2199 return WERR_INVALID_PARAM;
2202 switch (r->in.level) {
2204 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2205 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2209 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2212 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2215 werr = WERR_UNKNOWN_LEVEL;
2219 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2220 &ndr_table_samr.syntax_id,
2222 if (!W_ERROR_IS_OK(werr)) {
2226 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2227 SAMR_ACCESS_ENUM_DOMAINS |
2228 SAMR_ACCESS_LOOKUP_DOMAIN,
2233 if (!W_ERROR_IS_OK(werr)) {
2240 /* 3: 12 (DomainInfo2) */
2242 status = query_USER_MODALS_INFO_to_buffer(ctx,
2248 if (!NT_STATUS_IS_OK(status)) {
2249 werr = ntstatus_to_werror(status);
2254 if (ctx->disable_policy_handle_cache) {
2255 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2256 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2262 /****************************************************************
2263 ****************************************************************/
2265 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2266 struct NetUserModalsGet *r)
2268 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2271 /****************************************************************
2272 ****************************************************************/
2274 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2275 struct rpc_pipe_client *pipe_cli,
2276 struct policy_handle *domain_handle,
2277 struct samr_DomInfo1 *info1,
2278 struct samr_DomInfo3 *info3,
2279 struct samr_DomInfo12 *info12)
2282 union samr_DomainInfo dom_info;
2286 ZERO_STRUCT(dom_info);
2288 dom_info.info1 = *info1;
2290 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2294 NT_STATUS_NOT_OK_RETURN(status);
2299 ZERO_STRUCT(dom_info);
2301 dom_info.info3 = *info3;
2303 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2308 NT_STATUS_NOT_OK_RETURN(status);
2313 ZERO_STRUCT(dom_info);
2315 dom_info.info12 = *info12;
2317 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2322 NT_STATUS_NOT_OK_RETURN(status);
2325 return NT_STATUS_OK;
2328 /****************************************************************
2329 ****************************************************************/
2331 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2332 struct rpc_pipe_client *pipe_cli,
2333 struct policy_handle *domain_handle,
2334 struct USER_MODALS_INFO_0 *info0)
2337 struct samr_DomInfo1 dom_info_1;
2338 struct samr_DomInfo3 dom_info_3;
2340 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2349 NT_STATUS_NOT_OK_RETURN(status);
2351 dom_info_1.min_password_length =
2352 info0->usrmod0_min_passwd_len;
2353 dom_info_1.password_history_length =
2354 info0->usrmod0_password_hist_len;
2356 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2357 info0->usrmod0_max_passwd_age);
2358 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2359 info0->usrmod0_min_passwd_age);
2361 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2362 info0->usrmod0_force_logoff);
2364 return set_USER_MODALS_INFO_rpc(mem_ctx,
2372 /****************************************************************
2373 ****************************************************************/
2375 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2376 struct rpc_pipe_client *pipe_cli,
2377 struct policy_handle *domain_handle,
2378 struct USER_MODALS_INFO_3 *info3)
2381 struct samr_DomInfo12 dom_info_12;
2383 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2392 NT_STATUS_NOT_OK_RETURN(status);
2394 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2395 info3->usrmod3_lockout_duration);
2396 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2397 info3->usrmod3_lockout_observation_window);
2398 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2400 return set_USER_MODALS_INFO_rpc(mem_ctx,
2408 /****************************************************************
2409 ****************************************************************/
2411 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2412 struct rpc_pipe_client *pipe_cli,
2413 struct policy_handle *domain_handle,
2414 struct USER_MODALS_INFO_1001 *info1001)
2417 struct samr_DomInfo1 dom_info_1;
2419 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2428 NT_STATUS_NOT_OK_RETURN(status);
2430 dom_info_1.min_password_length =
2431 info1001->usrmod1001_min_passwd_len;
2433 return set_USER_MODALS_INFO_rpc(mem_ctx,
2441 /****************************************************************
2442 ****************************************************************/
2444 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2445 struct rpc_pipe_client *pipe_cli,
2446 struct policy_handle *domain_handle,
2447 struct USER_MODALS_INFO_1002 *info1002)
2450 struct samr_DomInfo1 dom_info_1;
2452 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2461 NT_STATUS_NOT_OK_RETURN(status);
2463 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2464 info1002->usrmod1002_max_passwd_age);
2466 return set_USER_MODALS_INFO_rpc(mem_ctx,
2474 /****************************************************************
2475 ****************************************************************/
2477 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2478 struct rpc_pipe_client *pipe_cli,
2479 struct policy_handle *domain_handle,
2480 struct USER_MODALS_INFO_1003 *info1003)
2483 struct samr_DomInfo1 dom_info_1;
2485 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2494 NT_STATUS_NOT_OK_RETURN(status);
2496 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2497 info1003->usrmod1003_min_passwd_age);
2499 return set_USER_MODALS_INFO_rpc(mem_ctx,
2507 /****************************************************************
2508 ****************************************************************/
2510 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2511 struct rpc_pipe_client *pipe_cli,
2512 struct policy_handle *domain_handle,
2513 struct USER_MODALS_INFO_1004 *info1004)
2516 struct samr_DomInfo3 dom_info_3;
2518 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2527 NT_STATUS_NOT_OK_RETURN(status);
2529 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2530 info1004->usrmod1004_force_logoff);
2532 return set_USER_MODALS_INFO_rpc(mem_ctx,
2540 /****************************************************************
2541 ****************************************************************/
2543 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2544 struct rpc_pipe_client *pipe_cli,
2545 struct policy_handle *domain_handle,
2546 struct USER_MODALS_INFO_1005 *info1005)
2549 struct samr_DomInfo1 dom_info_1;
2551 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2560 NT_STATUS_NOT_OK_RETURN(status);
2562 dom_info_1.password_history_length =
2563 info1005->usrmod1005_password_hist_len;
2565 return set_USER_MODALS_INFO_rpc(mem_ctx,
2573 /****************************************************************
2574 ****************************************************************/
2576 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2577 struct rpc_pipe_client *pipe_cli,
2579 struct policy_handle *domain_handle,
2580 struct dom_sid *domain_sid,
2583 struct USER_MODALS_INFO_0 *info0;
2584 struct USER_MODALS_INFO_3 *info3;
2585 struct USER_MODALS_INFO_1001 *info1001;
2586 struct USER_MODALS_INFO_1002 *info1002;
2587 struct USER_MODALS_INFO_1003 *info1003;
2588 struct USER_MODALS_INFO_1004 *info1004;
2589 struct USER_MODALS_INFO_1005 *info1005;
2592 return ERROR_INSUFFICIENT_BUFFER;
2597 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2598 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2603 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2604 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2609 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2610 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2615 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2616 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2621 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2622 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2627 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2628 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2633 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2634 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2643 return NT_STATUS_OK;
2646 /****************************************************************
2647 ****************************************************************/
2649 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2650 struct NetUserModalsSet *r)
2652 struct rpc_pipe_client *pipe_cli = NULL;
2656 struct policy_handle connect_handle, domain_handle;
2657 struct dom_sid2 *domain_sid = NULL;
2658 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2660 ZERO_STRUCT(connect_handle);
2661 ZERO_STRUCT(domain_handle);
2663 if (!r->in.buffer) {
2664 return WERR_INVALID_PARAM;
2667 switch (r->in.level) {
2669 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2670 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2671 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2672 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2679 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2680 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2683 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2684 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2690 werr = WERR_NOT_SUPPORTED;
2693 werr = WERR_UNKNOWN_LEVEL;
2697 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2698 &ndr_table_samr.syntax_id,
2700 if (!W_ERROR_IS_OK(werr)) {
2704 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2705 SAMR_ACCESS_ENUM_DOMAINS |
2706 SAMR_ACCESS_LOOKUP_DOMAIN,
2711 if (!W_ERROR_IS_OK(werr)) {
2715 status = set_USER_MODALS_INFO_buffer(ctx,
2721 if (!NT_STATUS_IS_OK(status)) {
2722 werr = ntstatus_to_werror(status);
2727 if (ctx->disable_policy_handle_cache) {
2728 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2729 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2735 /****************************************************************
2736 ****************************************************************/
2738 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2739 struct NetUserModalsSet *r)
2741 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2744 /****************************************************************
2745 ****************************************************************/
2747 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2749 const char *group_name,
2750 uint32_t attributes,
2752 uint32_t *num_entries)
2754 struct GROUP_USERS_INFO_0 u0;
2755 struct GROUP_USERS_INFO_1 u1;
2760 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2761 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2763 u0.grui0_name = NULL;
2766 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2767 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2771 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2772 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2774 u1.grui1_name = NULL;
2777 u1.grui1_attributes = attributes;
2779 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2780 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2783 return NT_STATUS_INVALID_INFO_CLASS;
2786 return NT_STATUS_OK;
2789 /****************************************************************
2790 ****************************************************************/
2792 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2793 struct NetUserGetGroups *r)
2795 struct rpc_pipe_client *pipe_cli = NULL;
2796 struct policy_handle connect_handle, domain_handle, user_handle;
2797 struct lsa_String lsa_account_name;
2798 struct dom_sid2 *domain_sid = NULL;
2799 struct samr_Ids user_rids, name_types;
2800 struct samr_RidWithAttributeArray *rid_array = NULL;
2801 struct lsa_Strings names;
2802 struct samr_Ids types;
2803 uint32_t *rids = NULL;
2806 uint32_t entries_read = 0;
2808 NTSTATUS status = NT_STATUS_OK;
2811 ZERO_STRUCT(connect_handle);
2812 ZERO_STRUCT(domain_handle);
2814 if (!r->out.buffer) {
2815 return WERR_INVALID_PARAM;
2818 *r->out.buffer = NULL;
2819 *r->out.entries_read = 0;
2820 *r->out.total_entries = 0;
2822 switch (r->in.level) {
2827 return WERR_UNKNOWN_LEVEL;
2830 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2831 &ndr_table_samr.syntax_id,
2833 if (!W_ERROR_IS_OK(werr)) {
2837 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2838 SAMR_ACCESS_ENUM_DOMAINS |
2839 SAMR_ACCESS_LOOKUP_DOMAIN,
2840 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2844 if (!W_ERROR_IS_OK(werr)) {
2848 init_lsa_String(&lsa_account_name, r->in.user_name);
2850 status = rpccli_samr_LookupNames(pipe_cli, ctx,
2856 if (!NT_STATUS_IS_OK(status)) {
2857 werr = ntstatus_to_werror(status);
2861 status = rpccli_samr_OpenUser(pipe_cli, ctx,
2863 SAMR_USER_ACCESS_GET_GROUPS,
2866 if (!NT_STATUS_IS_OK(status)) {
2867 werr = ntstatus_to_werror(status);
2871 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2874 if (!NT_STATUS_IS_OK(status)) {
2875 werr = ntstatus_to_werror(status);
2879 rids = talloc_array(ctx, uint32_t, rid_array->count);
2885 for (i=0; i < rid_array->count; i++) {
2886 rids[i] = rid_array->rids[i].rid;
2889 status = rpccli_samr_LookupRids(pipe_cli, ctx,
2895 if (!NT_STATUS_IS_OK(status) &&
2896 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
2897 werr = ntstatus_to_werror(status);
2901 for (i=0; i < names.count; i++) {
2902 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2904 names.names[i].string,
2905 rid_array->rids[i].attributes,
2908 if (!NT_STATUS_IS_OK(status)) {
2909 werr = ntstatus_to_werror(status);
2914 *r->out.entries_read = entries_read;
2915 *r->out.total_entries = entries_read;
2918 if (ctx->disable_policy_handle_cache) {
2919 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2920 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2926 /****************************************************************
2927 ****************************************************************/
2929 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2930 struct NetUserGetGroups *r)
2932 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
2935 /****************************************************************
2936 ****************************************************************/
2938 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
2939 struct NetUserSetGroups *r)
2941 struct rpc_pipe_client *pipe_cli = NULL;
2942 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
2943 struct lsa_String lsa_account_name;
2944 struct dom_sid2 *domain_sid = NULL;
2945 struct samr_Ids user_rids, name_types;
2946 struct samr_Ids group_rids;
2947 struct samr_RidWithAttributeArray *rid_array = NULL;
2948 struct lsa_String *lsa_names = NULL;
2950 uint32_t *add_rids = NULL;
2951 uint32_t *del_rids = NULL;
2952 size_t num_add_rids = 0;
2953 size_t num_del_rids = 0;
2955 uint32_t *member_rids = NULL;
2956 size_t num_member_rids = 0;
2958 struct GROUP_USERS_INFO_0 *i0 = NULL;
2959 struct GROUP_USERS_INFO_1 *i1 = NULL;
2963 NTSTATUS status = NT_STATUS_OK;
2966 ZERO_STRUCT(connect_handle);
2967 ZERO_STRUCT(domain_handle);
2969 if (!r->in.buffer) {
2970 return WERR_INVALID_PARAM;
2973 switch (r->in.level) {
2978 return WERR_UNKNOWN_LEVEL;
2981 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2982 &ndr_table_samr.syntax_id,
2984 if (!W_ERROR_IS_OK(werr)) {
2988 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2989 SAMR_ACCESS_ENUM_DOMAINS |
2990 SAMR_ACCESS_LOOKUP_DOMAIN,
2991 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2995 if (!W_ERROR_IS_OK(werr)) {
2999 init_lsa_String(&lsa_account_name, r->in.user_name);
3001 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3007 if (!NT_STATUS_IS_OK(status)) {
3008 werr = ntstatus_to_werror(status);
3012 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3014 SAMR_USER_ACCESS_GET_GROUPS,
3017 if (!NT_STATUS_IS_OK(status)) {
3018 werr = ntstatus_to_werror(status);
3022 switch (r->in.level) {
3024 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3027 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3031 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3037 for (i=0; i < r->in.num_entries; i++) {
3039 switch (r->in.level) {
3041 init_lsa_String(&lsa_names[i], i0->grui0_name);
3045 init_lsa_String(&lsa_names[i], i1->grui1_name);
3051 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3057 if (!NT_STATUS_IS_OK(status)) {
3058 werr = ntstatus_to_werror(status);
3062 member_rids = group_rids.ids;
3063 num_member_rids = group_rids.count;
3065 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3068 if (!NT_STATUS_IS_OK(status)) {
3069 werr = ntstatus_to_werror(status);
3075 for (i=0; i < r->in.num_entries; i++) {
3076 bool already_member = false;
3077 for (k=0; k < rid_array->count; k++) {
3078 if (member_rids[i] == rid_array->rids[k].rid) {
3079 already_member = true;
3083 if (!already_member) {
3084 if (!add_rid_to_array_unique(ctx,
3086 &add_rids, &num_add_rids)) {
3087 werr = WERR_GENERAL_FAILURE;
3095 for (k=0; k < rid_array->count; k++) {
3096 bool keep_member = false;
3097 for (i=0; i < r->in.num_entries; i++) {
3098 if (member_rids[i] == rid_array->rids[k].rid) {
3104 if (!add_rid_to_array_unique(ctx,
3105 rid_array->rids[k].rid,
3106 &del_rids, &num_del_rids)) {
3107 werr = WERR_GENERAL_FAILURE;
3115 for (i=0; i < num_add_rids; i++) {
3116 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3118 SAMR_GROUP_ACCESS_ADD_MEMBER,
3121 if (!NT_STATUS_IS_OK(status)) {
3122 werr = ntstatus_to_werror(status);
3126 status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
3130 if (!NT_STATUS_IS_OK(status)) {
3131 werr = ntstatus_to_werror(status);
3135 if (is_valid_policy_hnd(&group_handle)) {
3136 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3142 for (i=0; i < num_del_rids; i++) {
3143 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3145 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3148 if (!NT_STATUS_IS_OK(status)) {
3149 werr = ntstatus_to_werror(status);
3153 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
3156 if (!NT_STATUS_IS_OK(status)) {
3157 werr = ntstatus_to_werror(status);
3161 if (is_valid_policy_hnd(&group_handle)) {
3162 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3169 if (is_valid_policy_hnd(&group_handle)) {
3170 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3173 if (ctx->disable_policy_handle_cache) {
3174 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3175 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3181 /****************************************************************
3182 ****************************************************************/
3184 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3185 struct NetUserSetGroups *r)
3187 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3190 /****************************************************************
3191 ****************************************************************/
3193 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3195 const char *group_name,
3197 uint32_t *num_entries)
3199 struct LOCALGROUP_USERS_INFO_0 u0;
3203 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3204 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3206 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3207 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3210 return NT_STATUS_INVALID_INFO_CLASS;
3213 return NT_STATUS_OK;
3216 /****************************************************************
3217 ****************************************************************/
3219 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3220 struct NetUserGetLocalGroups *r)
3222 struct rpc_pipe_client *pipe_cli = NULL;
3223 struct policy_handle connect_handle, domain_handle, user_handle,
3225 struct lsa_String lsa_account_name;
3226 struct dom_sid2 *domain_sid = NULL;
3227 struct samr_Ids user_rids, name_types;
3228 struct samr_RidWithAttributeArray *rid_array = NULL;
3229 struct lsa_Strings names;
3230 struct samr_Ids types;
3231 uint32_t *rids = NULL;
3232 size_t num_rids = 0;
3233 struct dom_sid user_sid;
3234 struct lsa_SidArray sid_array;
3235 struct samr_Ids domain_rids;
3236 struct samr_Ids builtin_rids;
3239 uint32_t entries_read = 0;
3241 NTSTATUS status = NT_STATUS_OK;
3244 ZERO_STRUCT(connect_handle);
3245 ZERO_STRUCT(domain_handle);
3247 if (!r->out.buffer) {
3248 return WERR_INVALID_PARAM;
3251 *r->out.buffer = NULL;
3252 *r->out.entries_read = 0;
3253 *r->out.total_entries = 0;
3255 switch (r->in.level) {
3260 return WERR_UNKNOWN_LEVEL;
3263 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3264 &ndr_table_samr.syntax_id,
3266 if (!W_ERROR_IS_OK(werr)) {
3270 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3271 SAMR_ACCESS_ENUM_DOMAINS |
3272 SAMR_ACCESS_LOOKUP_DOMAIN,
3273 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3274 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3278 if (!W_ERROR_IS_OK(werr)) {
3282 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3283 SAMR_ACCESS_ENUM_DOMAINS |
3284 SAMR_ACCESS_LOOKUP_DOMAIN,
3285 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3286 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3289 if (!W_ERROR_IS_OK(werr)) {
3293 init_lsa_String(&lsa_account_name, r->in.user_name);
3295 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3301 if (!NT_STATUS_IS_OK(status)) {
3302 werr = ntstatus_to_werror(status);
3306 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3308 SAMR_USER_ACCESS_GET_GROUPS,
3311 if (!NT_STATUS_IS_OK(status)) {
3312 werr = ntstatus_to_werror(status);
3316 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3319 if (!NT_STATUS_IS_OK(status)) {
3320 werr = ntstatus_to_werror(status);
3324 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3329 sid_array.num_sids = rid_array->count + 1;
3330 sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
3331 if (!sid_array.sids) {
3336 sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid);
3337 if (!sid_array.sids[0].sid) {
3342 for (i=0; i < rid_array->count; i++) {
3345 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3350 sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid);
3351 if (!sid_array.sids[i+1].sid) {
3357 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3361 if (!NT_STATUS_IS_OK(status)) {
3362 werr = ntstatus_to_werror(status);
3366 for (i=0; i < domain_rids.count; i++) {
3367 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3368 &rids, &num_rids)) {
3374 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3378 if (!NT_STATUS_IS_OK(status)) {
3379 werr = ntstatus_to_werror(status);
3383 for (i=0; i < builtin_rids.count; i++) {
3384 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3385 &rids, &num_rids)) {
3391 status = rpccli_samr_LookupRids(pipe_cli, ctx,
3397 if (!NT_STATUS_IS_OK(status)) {
3398 werr = ntstatus_to_werror(status);
3402 for (i=0; i < names.count; i++) {
3403 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3405 names.names[i].string,
3408 if (!NT_STATUS_IS_OK(status)) {
3409 werr = ntstatus_to_werror(status);
3414 *r->out.entries_read = entries_read;
3415 *r->out.total_entries = entries_read;
3418 if (ctx->disable_policy_handle_cache) {
3419 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3420 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3426 /****************************************************************
3427 ****************************************************************/
3429 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3430 struct NetUserGetLocalGroups *r)
3432 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);