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"
33 /****************************************************************
34 ****************************************************************/
36 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
37 struct samr_UserInfo21 *info21)
39 uint32_t fields_present = 0;
40 struct samr_LogonHours zero_logon_hours;
41 struct lsa_BinaryString zero_parameters;
45 ZERO_STRUCT(zero_logon_hours);
46 ZERO_STRUCT(zero_parameters);
48 if (infoX->usriX_flags) {
49 fields_present |= SAMR_FIELD_ACCT_FLAGS;
51 if (infoX->usriX_name) {
52 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
54 if (infoX->usriX_password) {
55 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
57 if (infoX->usriX_flags) {
58 fields_present |= SAMR_FIELD_ACCT_FLAGS;
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->private_data.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->private_data_sensitive = 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;
300 NTSTATUS status, result;
301 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
304 return NT_STATUS_INVALID_PARAMETER;
307 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
309 ZERO_STRUCT(user_info);
311 if (uX->usriX_password) {
313 user_info.info25.info = info21;
315 init_samr_CryptPasswordEx(uX->usriX_password,
317 &user_info.info25.password);
319 status = dcerpc_samr_SetUserInfo2(b, talloc_tos(),
324 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
326 user_info.info23.info = info21;
328 init_samr_CryptPassword(uX->usriX_password,
330 &user_info.info23.password);
332 status = dcerpc_samr_SetUserInfo2(b, talloc_tos(),
337 if (!NT_STATUS_IS_OK(status)) {
342 if (!NT_STATUS_IS_OK(status)) {
347 user_info.info21 = info21;
349 status = dcerpc_samr_SetUserInfo(b, talloc_tos(),
354 if (!NT_STATUS_IS_OK(status)) {
362 /****************************************************************
363 ****************************************************************/
365 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
366 struct NetUserAdd *r)
368 struct rpc_pipe_client *pipe_cli = NULL;
369 NTSTATUS status, result;
371 struct policy_handle connect_handle, domain_handle, user_handle;
372 struct lsa_String lsa_account_name;
373 struct dom_sid2 *domain_sid = NULL;
374 union samr_UserInfo *user_info = NULL;
375 struct samr_PwInfo pw_info;
376 uint32_t access_granted = 0;
378 struct USER_INFO_X uX;
379 struct dcerpc_binding_handle *b = NULL;
381 ZERO_STRUCT(connect_handle);
382 ZERO_STRUCT(domain_handle);
383 ZERO_STRUCT(user_handle);
386 return WERR_INVALID_PARAM;
389 switch (r->in.level) {
396 werr = WERR_NOT_SUPPORTED;
400 werr = libnetapi_open_pipe(ctx, r->in.server_name,
401 &ndr_table_samr.syntax_id,
403 if (!W_ERROR_IS_OK(werr)) {
407 b = pipe_cli->binding_handle;
409 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
410 if (!NT_STATUS_IS_OK(status)) {
411 werr = ntstatus_to_werror(status);
415 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
416 SAMR_ACCESS_ENUM_DOMAINS |
417 SAMR_ACCESS_LOOKUP_DOMAIN,
418 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
419 SAMR_DOMAIN_ACCESS_CREATE_USER |
420 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
424 if (!W_ERROR_IS_OK(werr)) {
428 init_lsa_String(&lsa_account_name, uX.usriX_name);
430 status = dcerpc_samr_CreateUser2(b, talloc_tos(),
436 SAMR_USER_ACCESS_SET_PASSWORD |
437 SAMR_USER_ACCESS_SET_ATTRIBUTES |
438 SAMR_USER_ACCESS_GET_ATTRIBUTES,
443 if (!NT_STATUS_IS_OK(status)) {
444 werr = ntstatus_to_werror(status);
447 if (!NT_STATUS_IS_OK(result)) {
448 werr = ntstatus_to_werror(result);
452 status = dcerpc_samr_QueryUserInfo(b, talloc_tos(),
457 if (!NT_STATUS_IS_OK(status)) {
458 werr = ntstatus_to_werror(status);
461 if (!NT_STATUS_IS_OK(result)) {
462 werr = ntstatus_to_werror(result);
466 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
467 werr = WERR_INVALID_PARAM;
471 status = dcerpc_samr_GetUserPwInfo(b, talloc_tos(),
475 if (!NT_STATUS_IS_OK(status)) {
476 werr = ntstatus_to_werror(status);
479 if (!NT_STATUS_IS_OK(result)) {
480 werr = ntstatus_to_werror(result);
484 uX.usriX_flags |= ACB_NORMAL;
486 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
487 &pipe_cli->auth->user_session_key,
490 if (!NT_STATUS_IS_OK(status)) {
491 werr = ntstatus_to_werror(status);
499 dcerpc_samr_DeleteUser(b, talloc_tos(),
504 if (is_valid_policy_hnd(&user_handle) && b) {
505 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
508 if (ctx->disable_policy_handle_cache) {
509 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
510 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
516 /****************************************************************
517 ****************************************************************/
519 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
520 struct NetUserAdd *r)
522 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
525 /****************************************************************
526 ****************************************************************/
528 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
529 struct NetUserDel *r)
531 struct rpc_pipe_client *pipe_cli = NULL;
532 NTSTATUS status, result;
534 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
535 struct lsa_String lsa_account_name;
536 struct samr_Ids user_rids, name_types;
537 struct dom_sid2 *domain_sid = NULL;
538 struct dom_sid2 user_sid;
539 struct dcerpc_binding_handle *b = NULL;
541 ZERO_STRUCT(connect_handle);
542 ZERO_STRUCT(builtin_handle);
543 ZERO_STRUCT(domain_handle);
544 ZERO_STRUCT(user_handle);
546 werr = libnetapi_open_pipe(ctx, r->in.server_name,
547 &ndr_table_samr.syntax_id,
550 if (!W_ERROR_IS_OK(werr)) {
554 b = pipe_cli->binding_handle;
556 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
557 SAMR_ACCESS_ENUM_DOMAINS |
558 SAMR_ACCESS_LOOKUP_DOMAIN,
559 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
563 if (!W_ERROR_IS_OK(werr)) {
567 status = dcerpc_samr_OpenDomain(b, talloc_tos(),
569 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
570 CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
573 if (!NT_STATUS_IS_OK(status)) {
574 werr = ntstatus_to_werror(status);
577 if (!NT_STATUS_IS_OK(result)) {
578 werr = ntstatus_to_werror(result);
582 init_lsa_String(&lsa_account_name, r->in.user_name);
584 status = dcerpc_samr_LookupNames(b, talloc_tos(),
591 if (!NT_STATUS_IS_OK(status)) {
592 werr = ntstatus_to_werror(status);
595 if (!NT_STATUS_IS_OK(result)) {
596 werr = ntstatus_to_werror(result);
600 status = dcerpc_samr_OpenUser(b, talloc_tos(),
606 if (!NT_STATUS_IS_OK(status)) {
607 werr = ntstatus_to_werror(status);
610 if (!NT_STATUS_IS_OK(result)) {
611 werr = ntstatus_to_werror(result);
615 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
617 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, talloc_tos(),
621 if (!NT_STATUS_IS_OK(status)) {
622 werr = ntstatus_to_werror(status);
625 if (!NT_STATUS_IS_OK(result)) {
626 werr = ntstatus_to_werror(result);
630 status = dcerpc_samr_DeleteUser(b, talloc_tos(),
633 if (!NT_STATUS_IS_OK(status)) {
634 werr = ntstatus_to_werror(status);
637 if (!NT_STATUS_IS_OK(result)) {
638 werr = ntstatus_to_werror(result);
645 if (is_valid_policy_hnd(&user_handle)) {
646 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
649 if (ctx->disable_policy_handle_cache) {
650 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
651 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
652 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
658 /****************************************************************
659 ****************************************************************/
661 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
662 struct NetUserDel *r)
664 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
667 /****************************************************************
668 ****************************************************************/
670 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
671 struct rpc_pipe_client *pipe_cli,
672 struct policy_handle *domain_handle,
673 struct policy_handle *builtin_handle,
674 const char *user_name,
675 const struct dom_sid *domain_sid,
678 struct samr_UserInfo21 **info21,
679 struct sec_desc_buf **sec_desc,
680 uint32_t *auth_flag_p)
682 NTSTATUS status, result;
684 struct policy_handle user_handle;
685 union samr_UserInfo *user_info = NULL;
686 struct samr_RidWithAttributeArray *rid_array = NULL;
687 uint32_t access_mask = SEC_STD_READ_CONTROL |
688 SAMR_USER_ACCESS_GET_ATTRIBUTES |
689 SAMR_USER_ACCESS_GET_NAME_ETC;
690 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
692 ZERO_STRUCT(user_handle);
698 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
699 SAMR_USER_ACCESS_GET_GROUPS;
705 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
706 SAMR_USER_ACCESS_GET_GROUPS |
707 SAMR_USER_ACCESS_GET_LOCALE;
714 return NT_STATUS_INVALID_LEVEL;
721 status = dcerpc_samr_OpenUser(b, mem_ctx,
727 if (!NT_STATUS_IS_OK(status)) {
730 if (!NT_STATUS_IS_OK(result)) {
735 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
740 if (!NT_STATUS_IS_OK(status)) {
743 if (!NT_STATUS_IS_OK(result)) {
748 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
753 if (!NT_STATUS_IS_OK(status)) {
756 if (!NT_STATUS_IS_OK(result)) {
761 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
763 struct lsa_SidArray sid_array;
764 struct samr_Ids alias_rids;
766 uint32_t auth_flag = 0;
769 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
773 if (!NT_STATUS_IS_OK(status)) {
776 if (!NT_STATUS_IS_OK(result)) {
781 sid_array.num_sids = rid_array->count + 1;
782 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
784 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
786 for (i=0; i<rid_array->count; i++) {
787 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
788 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
789 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
792 sid_compose(&sid, domain_sid, rid);
793 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
794 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
796 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
801 if (!NT_STATUS_IS_OK(status)) {
804 if (!NT_STATUS_IS_OK(result)) {
809 for (i=0; i<alias_rids.count; i++) {
810 switch (alias_rids.ids[i]) {
811 case 550: /* Print Operators */
812 auth_flag |= AF_OP_PRINT;
814 case 549: /* Server Operators */
815 auth_flag |= AF_OP_SERVER;
817 case 548: /* Account Operators */
818 auth_flag |= AF_OP_ACCOUNTS;
826 *auth_flag_p = auth_flag;
830 *info21 = &user_info->info21;
833 if (is_valid_policy_hnd(&user_handle)) {
834 dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
840 /****************************************************************
841 ****************************************************************/
843 static uint32_t samr_rid_to_priv_level(uint32_t rid)
846 case DOMAIN_RID_ADMINISTRATOR:
847 return USER_PRIV_ADMIN;
848 case DOMAIN_RID_GUEST:
849 return USER_PRIV_GUEST;
851 return USER_PRIV_USER;
855 /****************************************************************
856 ****************************************************************/
858 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
860 uint32_t fl = UF_SCRIPT; /* god knows why */
862 fl |= ds_acb2uf(acb);
867 /****************************************************************
868 ****************************************************************/
870 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
871 const struct samr_UserInfo21 *i21,
872 struct USER_INFO_1 *i)
875 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
876 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
877 i->usri1_password = NULL;
878 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
879 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
880 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
881 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
882 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
883 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
888 /****************************************************************
889 ****************************************************************/
891 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
892 const struct samr_UserInfo21 *i21,
894 struct USER_INFO_2 *i)
898 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
899 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
900 i->usri2_password = NULL;
901 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
902 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
903 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
904 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
905 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
906 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
907 i->usri2_auth_flags = auth_flag;
908 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
909 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
910 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
911 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
912 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
913 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
914 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
915 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
916 i->usri2_units_per_week = i21->logon_hours.units_per_week;
917 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
918 i->usri2_bad_pw_count = i21->bad_password_count;
919 i->usri2_num_logons = i21->logon_count;
920 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
921 i->usri2_country_code = i21->country_code;
922 i->usri2_code_page = i21->code_page;
927 /****************************************************************
928 ****************************************************************/
930 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
931 const struct samr_UserInfo21 *i21,
933 struct USER_INFO_3 *i)
937 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
938 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
939 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
940 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
941 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
942 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
943 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
944 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
945 i->usri3_auth_flags = auth_flag;
946 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
947 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
948 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
949 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
950 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
951 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
952 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
953 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
954 i->usri3_units_per_week = i21->logon_hours.units_per_week;
955 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
956 i->usri3_bad_pw_count = i21->bad_password_count;
957 i->usri3_num_logons = i21->logon_count;
958 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
959 i->usri3_country_code = i21->country_code;
960 i->usri3_code_page = i21->code_page;
961 i->usri3_user_id = i21->rid;
962 i->usri3_primary_group_id = i21->primary_gid;
963 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
964 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
965 i->usri3_password_expired = i21->password_expired;
970 /****************************************************************
971 ****************************************************************/
973 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
974 const struct samr_UserInfo21 *i21,
976 struct dom_sid *domain_sid,
977 struct USER_INFO_4 *i)
983 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
984 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
985 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
986 i->usri4_password = NULL;
987 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
988 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
989 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
990 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
991 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
992 i->usri4_auth_flags = auth_flag;
993 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
994 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
995 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
996 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
997 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
998 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
999 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
1000 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1001 i->usri4_units_per_week = i21->logon_hours.units_per_week;
1002 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1003 i->usri4_bad_pw_count = i21->bad_password_count;
1004 i->usri4_num_logons = i21->logon_count;
1005 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1006 i->usri4_country_code = i21->country_code;
1007 i->usri4_code_page = i21->code_page;
1008 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1009 return NT_STATUS_NO_MEMORY;
1011 i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1012 i->usri4_primary_group_id = i21->primary_gid;
1013 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
1014 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
1015 i->usri4_password_expired = i21->password_expired;
1017 return NT_STATUS_OK;
1020 /****************************************************************
1021 ****************************************************************/
1023 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
1024 const struct samr_UserInfo21 *i21,
1025 struct USER_INFO_10 *i)
1029 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
1030 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
1031 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
1032 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1033 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1035 return NT_STATUS_OK;
1038 /****************************************************************
1039 ****************************************************************/
1041 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
1042 const struct samr_UserInfo21 *i21,
1044 struct USER_INFO_11 *i)
1048 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
1049 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
1050 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
1051 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1052 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1053 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
1054 i->usri11_auth_flags = auth_flag;
1055 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1056 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1057 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1058 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
1059 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
1060 i->usri11_bad_pw_count = i21->bad_password_count;
1061 i->usri11_num_logons = i21->logon_count;
1062 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1063 i->usri11_country_code = i21->country_code;
1064 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1065 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1066 i->usri11_units_per_week = i21->logon_hours.units_per_week;
1067 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1068 i->usri11_code_page = i21->code_page;
1070 return NT_STATUS_OK;
1073 /****************************************************************
1074 ****************************************************************/
1076 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
1077 const struct samr_UserInfo21 *i21,
1078 struct USER_INFO_20 *i)
1082 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1083 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1084 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1085 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1086 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1087 i->usri20_user_id = i21->rid;
1089 return NT_STATUS_OK;
1092 /****************************************************************
1093 ****************************************************************/
1095 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1096 const struct samr_UserInfo21 *i21,
1097 struct dom_sid *domain_sid,
1098 struct USER_INFO_23 *i)
1104 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1105 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1106 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1107 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1108 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1109 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1110 return NT_STATUS_NO_MEMORY;
1112 i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1114 return NT_STATUS_OK;
1117 /****************************************************************
1118 ****************************************************************/
1120 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1121 struct rpc_pipe_client *pipe_cli,
1122 struct dom_sid *domain_sid,
1123 struct policy_handle *domain_handle,
1124 struct policy_handle *builtin_handle,
1125 const char *user_name,
1129 uint32_t *num_entries)
1133 struct samr_UserInfo21 *info21 = NULL;
1134 struct sec_desc_buf *sec_desc = NULL;
1135 uint32_t auth_flag = 0;
1137 struct USER_INFO_0 info0;
1138 struct USER_INFO_1 info1;
1139 struct USER_INFO_2 info2;
1140 struct USER_INFO_3 info3;
1141 struct USER_INFO_4 info4;
1142 struct USER_INFO_10 info10;
1143 struct USER_INFO_11 info11;
1144 struct USER_INFO_20 info20;
1145 struct USER_INFO_23 info23;
1159 return NT_STATUS_INVALID_LEVEL;
1163 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1164 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1166 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1167 (struct USER_INFO_0 **)buffer, num_entries);
1169 return NT_STATUS_OK;
1172 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1183 if (!NT_STATUS_IS_OK(status)) {
1189 /* already returned above */
1192 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1193 NT_STATUS_NOT_OK_RETURN(status);
1195 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1196 (struct USER_INFO_1 **)buffer, num_entries);
1200 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1201 NT_STATUS_NOT_OK_RETURN(status);
1203 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1204 (struct USER_INFO_2 **)buffer, num_entries);
1208 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1209 NT_STATUS_NOT_OK_RETURN(status);
1211 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1212 (struct USER_INFO_3 **)buffer, num_entries);
1216 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1217 NT_STATUS_NOT_OK_RETURN(status);
1219 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1220 (struct USER_INFO_4 **)buffer, num_entries);
1224 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1225 NT_STATUS_NOT_OK_RETURN(status);
1227 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1228 (struct USER_INFO_10 **)buffer, num_entries);
1232 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1233 NT_STATUS_NOT_OK_RETURN(status);
1235 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1236 (struct USER_INFO_11 **)buffer, num_entries);
1240 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1241 NT_STATUS_NOT_OK_RETURN(status);
1243 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1244 (struct USER_INFO_20 **)buffer, num_entries);
1248 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1249 NT_STATUS_NOT_OK_RETURN(status);
1251 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1252 (struct USER_INFO_23 **)buffer, num_entries);
1255 return NT_STATUS_INVALID_LEVEL;
1262 /****************************************************************
1263 ****************************************************************/
1265 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1266 struct NetUserEnum *r)
1268 struct rpc_pipe_client *pipe_cli = NULL;
1269 struct policy_handle connect_handle;
1270 struct dom_sid2 *domain_sid = NULL;
1271 struct policy_handle domain_handle, builtin_handle;
1272 struct samr_SamArray *sam = NULL;
1273 uint32_t filter = ACB_NORMAL;
1275 uint32_t entries_read = 0;
1277 NTSTATUS status = NT_STATUS_OK;
1278 NTSTATUS result = NT_STATUS_OK;
1280 struct dcerpc_binding_handle *b = NULL;
1282 ZERO_STRUCT(connect_handle);
1283 ZERO_STRUCT(domain_handle);
1284 ZERO_STRUCT(builtin_handle);
1286 if (!r->out.buffer) {
1287 return WERR_INVALID_PARAM;
1290 *r->out.buffer = NULL;
1291 *r->out.entries_read = 0;
1293 switch (r->in.level) {
1305 return WERR_UNKNOWN_LEVEL;
1308 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1309 &ndr_table_samr.syntax_id,
1311 if (!W_ERROR_IS_OK(werr)) {
1315 b = pipe_cli->binding_handle;
1317 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1318 SAMR_ACCESS_ENUM_DOMAINS |
1319 SAMR_ACCESS_LOOKUP_DOMAIN,
1320 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1321 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1324 if (!W_ERROR_IS_OK(werr)) {
1328 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1329 SAMR_ACCESS_ENUM_DOMAINS |
1330 SAMR_ACCESS_LOOKUP_DOMAIN,
1331 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1332 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1333 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1337 if (!W_ERROR_IS_OK(werr)) {
1341 switch (r->in.filter) {
1342 case FILTER_NORMAL_ACCOUNT:
1343 filter = ACB_NORMAL;
1345 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1346 filter = ACB_TEMPDUP;
1348 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1349 filter = ACB_DOMTRUST;
1351 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1352 filter = ACB_WSTRUST;
1354 case FILTER_SERVER_TRUST_ACCOUNT:
1355 filter = ACB_SVRTRUST;
1361 status = dcerpc_samr_EnumDomainUsers(b,
1364 r->in.resume_handle,
1370 if (!NT_STATUS_IS_OK(status)) {
1371 werr = ntstatus_to_werror(status);
1374 werr = ntstatus_to_werror(result);
1375 if (NT_STATUS_IS_ERR(result)) {
1379 for (i=0; i < sam->count; i++) {
1381 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1385 sam->entries[i].name.string,
1386 sam->entries[i].idx,
1389 r->out.entries_read);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 werr = ntstatus_to_werror(status);
1398 if (NT_STATUS_IS_OK(result) ||
1399 NT_STATUS_IS_ERR(result)) {
1401 if (ctx->disable_policy_handle_cache) {
1402 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1403 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1404 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1411 /****************************************************************
1412 ****************************************************************/
1414 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1415 struct NetUserEnum *r)
1417 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1420 /****************************************************************
1421 ****************************************************************/
1423 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1424 struct samr_DispInfoGeneral *info,
1425 uint32_t *entries_read,
1428 struct NET_DISPLAY_USER *user = NULL;
1431 user = TALLOC_ZERO_ARRAY(mem_ctx,
1432 struct NET_DISPLAY_USER,
1434 W_ERROR_HAVE_NO_MEMORY(user);
1436 for (i = 0; i < info->count; i++) {
1437 user[i].usri1_name = talloc_strdup(mem_ctx,
1438 info->entries[i].account_name.string);
1439 user[i].usri1_comment = talloc_strdup(mem_ctx,
1440 info->entries[i].description.string);
1441 user[i].usri1_flags =
1442 info->entries[i].acct_flags;
1443 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1444 info->entries[i].full_name.string);
1445 user[i].usri1_user_id =
1446 info->entries[i].rid;
1447 user[i].usri1_next_index =
1448 info->entries[i].idx;
1450 if (!user[i].usri1_name) {
1455 *buffer = talloc_memdup(mem_ctx, user,
1456 sizeof(struct NET_DISPLAY_USER) * info->count);
1457 W_ERROR_HAVE_NO_MEMORY(*buffer);
1459 *entries_read = info->count;
1464 /****************************************************************
1465 ****************************************************************/
1467 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1468 struct samr_DispInfoFull *info,
1469 uint32_t *entries_read,
1472 struct NET_DISPLAY_MACHINE *machine = NULL;
1475 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1476 struct NET_DISPLAY_MACHINE,
1478 W_ERROR_HAVE_NO_MEMORY(machine);
1480 for (i = 0; i < info->count; i++) {
1481 machine[i].usri2_name = talloc_strdup(mem_ctx,
1482 info->entries[i].account_name.string);
1483 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1484 info->entries[i].description.string);
1485 machine[i].usri2_flags =
1486 info->entries[i].acct_flags;
1487 machine[i].usri2_user_id =
1488 info->entries[i].rid;
1489 machine[i].usri2_next_index =
1490 info->entries[i].idx;
1492 if (!machine[i].usri2_name) {
1497 *buffer = talloc_memdup(mem_ctx, machine,
1498 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1499 W_ERROR_HAVE_NO_MEMORY(*buffer);
1501 *entries_read = info->count;
1506 /****************************************************************
1507 ****************************************************************/
1509 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1510 struct samr_DispInfoFullGroups *info,
1511 uint32_t *entries_read,
1514 struct NET_DISPLAY_GROUP *group = NULL;
1517 group = TALLOC_ZERO_ARRAY(mem_ctx,
1518 struct NET_DISPLAY_GROUP,
1520 W_ERROR_HAVE_NO_MEMORY(group);
1522 for (i = 0; i < info->count; i++) {
1523 group[i].grpi3_name = talloc_strdup(mem_ctx,
1524 info->entries[i].account_name.string);
1525 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1526 info->entries[i].description.string);
1527 group[i].grpi3_group_id =
1528 info->entries[i].rid;
1529 group[i].grpi3_attributes =
1530 info->entries[i].acct_flags;
1531 group[i].grpi3_next_index =
1532 info->entries[i].idx;
1534 if (!group[i].grpi3_name) {
1539 *buffer = talloc_memdup(mem_ctx, group,
1540 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1541 W_ERROR_HAVE_NO_MEMORY(*buffer);
1543 *entries_read = info->count;
1549 /****************************************************************
1550 ****************************************************************/
1552 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1553 union samr_DispInfo *info,
1555 uint32_t *entries_read,
1560 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1565 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1570 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1578 return WERR_UNKNOWN_LEVEL;
1581 /****************************************************************
1582 ****************************************************************/
1584 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1585 struct NetQueryDisplayInformation *r)
1587 struct rpc_pipe_client *pipe_cli = NULL;
1588 struct policy_handle connect_handle;
1589 struct dom_sid2 *domain_sid = NULL;
1590 struct policy_handle domain_handle;
1591 union samr_DispInfo info;
1592 struct dcerpc_binding_handle *b = NULL;
1594 uint32_t total_size = 0;
1595 uint32_t returned_size = 0;
1597 NTSTATUS status = NT_STATUS_OK;
1598 NTSTATUS result = NT_STATUS_OK;
1602 *r->out.entries_read = 0;
1604 ZERO_STRUCT(connect_handle);
1605 ZERO_STRUCT(domain_handle);
1607 switch (r->in.level) {
1613 return WERR_UNKNOWN_LEVEL;
1616 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1617 &ndr_table_samr.syntax_id,
1619 if (!W_ERROR_IS_OK(werr)) {
1623 b = pipe_cli->binding_handle;
1625 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1626 SAMR_ACCESS_ENUM_DOMAINS |
1627 SAMR_ACCESS_LOOKUP_DOMAIN,
1628 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1629 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1630 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1634 if (!W_ERROR_IS_OK(werr)) {
1638 status = dcerpc_samr_QueryDisplayInfo2(b,
1643 r->in.entries_requested,
1649 if (!NT_STATUS_IS_OK(status)) {
1650 werr = ntstatus_to_werror(status);
1653 werr = ntstatus_to_werror(result);
1654 if (NT_STATUS_IS_ERR(result)) {
1658 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1660 r->out.entries_read,
1662 if (!W_ERROR_IS_OK(werr_tmp)) {
1667 if (NT_STATUS_IS_OK(result) ||
1668 NT_STATUS_IS_ERR(result)) {
1670 if (ctx->disable_policy_handle_cache) {
1671 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1672 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1680 /****************************************************************
1681 ****************************************************************/
1684 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1685 struct NetQueryDisplayInformation *r)
1687 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1690 /****************************************************************
1691 ****************************************************************/
1693 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1694 struct NetUserChangePassword *r)
1696 return WERR_NOT_SUPPORTED;
1699 /****************************************************************
1700 ****************************************************************/
1702 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1703 struct NetUserChangePassword *r)
1705 return WERR_NOT_SUPPORTED;
1708 /****************************************************************
1709 ****************************************************************/
1711 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1712 struct NetUserGetInfo *r)
1714 struct rpc_pipe_client *pipe_cli = NULL;
1715 NTSTATUS status, result;
1718 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1719 struct lsa_String lsa_account_name;
1720 struct dom_sid2 *domain_sid = NULL;
1721 struct samr_Ids user_rids, name_types;
1722 uint32_t num_entries = 0;
1723 struct dcerpc_binding_handle *b = NULL;
1725 ZERO_STRUCT(connect_handle);
1726 ZERO_STRUCT(domain_handle);
1727 ZERO_STRUCT(builtin_handle);
1728 ZERO_STRUCT(user_handle);
1730 if (!r->out.buffer) {
1731 return WERR_INVALID_PARAM;
1734 switch (r->in.level) {
1746 werr = WERR_UNKNOWN_LEVEL;
1750 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1751 &ndr_table_samr.syntax_id,
1753 if (!W_ERROR_IS_OK(werr)) {
1757 b = pipe_cli->binding_handle;
1759 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1760 SAMR_ACCESS_ENUM_DOMAINS |
1761 SAMR_ACCESS_LOOKUP_DOMAIN,
1762 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1766 if (!W_ERROR_IS_OK(werr)) {
1770 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1771 SAMR_ACCESS_ENUM_DOMAINS |
1772 SAMR_ACCESS_LOOKUP_DOMAIN,
1773 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1774 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1777 if (!W_ERROR_IS_OK(werr)) {
1781 init_lsa_String(&lsa_account_name, r->in.user_name);
1783 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1790 if (!NT_STATUS_IS_OK(status)) {
1791 werr = ntstatus_to_werror(status);
1794 if (!NT_STATUS_IS_OK(result)) {
1795 werr = ntstatus_to_werror(result);
1799 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1808 if (!NT_STATUS_IS_OK(status)) {
1809 werr = ntstatus_to_werror(status);
1814 if (is_valid_policy_hnd(&user_handle) && b) {
1815 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1818 if (ctx->disable_policy_handle_cache) {
1819 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1820 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1826 /****************************************************************
1827 ****************************************************************/
1829 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1830 struct NetUserGetInfo *r)
1832 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1835 /****************************************************************
1836 ****************************************************************/
1838 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1839 struct NetUserSetInfo *r)
1841 struct rpc_pipe_client *pipe_cli = NULL;
1842 NTSTATUS status, result;
1845 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1846 struct lsa_String lsa_account_name;
1847 struct dom_sid2 *domain_sid = NULL;
1848 struct samr_Ids user_rids, name_types;
1849 uint32_t user_mask = 0;
1851 struct USER_INFO_X uX;
1852 struct dcerpc_binding_handle *b = NULL;
1854 ZERO_STRUCT(connect_handle);
1855 ZERO_STRUCT(domain_handle);
1856 ZERO_STRUCT(builtin_handle);
1857 ZERO_STRUCT(user_handle);
1859 if (!r->in.buffer) {
1860 return WERR_INVALID_PARAM;
1863 switch (r->in.level) {
1865 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1868 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1877 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1881 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1883 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1884 SAMR_USER_ACCESS_GET_GROUPS;
1887 user_mask = SEC_STD_READ_CONTROL |
1889 SAMR_USER_ACCESS_GET_GROUPS |
1890 SAMR_USER_ACCESS_SET_PASSWORD |
1891 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1892 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1893 SAMR_USER_ACCESS_SET_LOC_COM;
1905 werr = WERR_NOT_SUPPORTED;
1908 werr = WERR_UNKNOWN_LEVEL;
1912 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1913 &ndr_table_samr.syntax_id,
1915 if (!W_ERROR_IS_OK(werr)) {
1919 b = pipe_cli->binding_handle;
1921 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1922 SAMR_ACCESS_ENUM_DOMAINS |
1923 SAMR_ACCESS_LOOKUP_DOMAIN,
1924 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1925 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1929 if (!W_ERROR_IS_OK(werr)) {
1933 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1934 SAMR_ACCESS_ENUM_DOMAINS |
1935 SAMR_ACCESS_LOOKUP_DOMAIN,
1936 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1937 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1940 if (!W_ERROR_IS_OK(werr)) {
1944 init_lsa_String(&lsa_account_name, r->in.user_name);
1946 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1953 if (!NT_STATUS_IS_OK(status)) {
1954 werr = ntstatus_to_werror(status);
1957 if (!NT_STATUS_IS_OK(result)) {
1958 werr = ntstatus_to_werror(result);
1962 status = dcerpc_samr_OpenUser(b, talloc_tos(),
1968 if (!NT_STATUS_IS_OK(status)) {
1969 werr = ntstatus_to_werror(status);
1972 if (!NT_STATUS_IS_OK(result)) {
1973 werr = ntstatus_to_werror(result);
1977 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1978 if (!NT_STATUS_IS_OK(status)) {
1979 werr = ntstatus_to_werror(status);
1983 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1984 &pipe_cli->auth->user_session_key,
1987 if (!NT_STATUS_IS_OK(status)) {
1988 werr = ntstatus_to_werror(status);
1995 if (is_valid_policy_hnd(&user_handle) && b) {
1996 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1999 if (ctx->disable_policy_handle_cache) {
2000 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2001 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
2002 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2008 /****************************************************************
2009 ****************************************************************/
2011 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
2012 struct NetUserSetInfo *r)
2014 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
2017 /****************************************************************
2018 ****************************************************************/
2020 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2021 struct rpc_pipe_client *pipe_cli,
2022 struct policy_handle *domain_handle,
2023 struct samr_DomInfo1 *info1,
2024 struct samr_DomInfo3 *info3,
2025 struct samr_DomInfo5 *info5,
2026 struct samr_DomInfo6 *info6,
2027 struct samr_DomInfo7 *info7,
2028 struct samr_DomInfo12 *info12)
2030 NTSTATUS status, result;
2031 union samr_DomainInfo *dom_info = NULL;
2032 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2035 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2040 NT_STATUS_NOT_OK_RETURN(status);
2041 NT_STATUS_NOT_OK_RETURN(result);
2043 *info1 = dom_info->info1;
2047 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2052 NT_STATUS_NOT_OK_RETURN(status);
2053 NT_STATUS_NOT_OK_RETURN(result);
2055 *info3 = dom_info->info3;
2059 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2064 NT_STATUS_NOT_OK_RETURN(status);
2065 NT_STATUS_NOT_OK_RETURN(result);
2067 *info5 = dom_info->info5;
2071 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2076 NT_STATUS_NOT_OK_RETURN(status);
2077 NT_STATUS_NOT_OK_RETURN(result);
2079 *info6 = dom_info->info6;
2083 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2088 NT_STATUS_NOT_OK_RETURN(status);
2089 NT_STATUS_NOT_OK_RETURN(result);
2091 *info7 = dom_info->info7;
2095 status = dcerpc_samr_QueryDomainInfo2(b, mem_ctx,
2100 NT_STATUS_NOT_OK_RETURN(status);
2101 NT_STATUS_NOT_OK_RETURN(result);
2103 *info12 = dom_info->info12;
2106 return NT_STATUS_OK;
2109 /****************************************************************
2110 ****************************************************************/
2112 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
2113 struct rpc_pipe_client *pipe_cli,
2114 struct policy_handle *domain_handle,
2115 struct USER_MODALS_INFO_0 *info0)
2118 struct samr_DomInfo1 dom_info1;
2119 struct samr_DomInfo3 dom_info3;
2121 ZERO_STRUCTP(info0);
2123 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2132 NT_STATUS_NOT_OK_RETURN(status);
2134 info0->usrmod0_min_passwd_len =
2135 dom_info1.min_password_length;
2136 info0->usrmod0_max_passwd_age =
2137 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2138 info0->usrmod0_min_passwd_age =
2139 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2140 info0->usrmod0_password_hist_len =
2141 dom_info1.password_history_length;
2143 info0->usrmod0_force_logoff =
2144 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2146 return NT_STATUS_OK;
2149 /****************************************************************
2150 ****************************************************************/
2152 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2153 struct rpc_pipe_client *pipe_cli,
2154 struct policy_handle *domain_handle,
2155 struct USER_MODALS_INFO_1 *info1)
2158 struct samr_DomInfo6 dom_info6;
2159 struct samr_DomInfo7 dom_info7;
2161 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2170 NT_STATUS_NOT_OK_RETURN(status);
2172 info1->usrmod1_primary =
2173 talloc_strdup(mem_ctx, dom_info6.primary.string);
2175 info1->usrmod1_role = dom_info7.role;
2177 return NT_STATUS_OK;
2180 /****************************************************************
2181 ****************************************************************/
2183 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2184 struct rpc_pipe_client *pipe_cli,
2185 struct policy_handle *domain_handle,
2186 struct dom_sid *domain_sid,
2187 struct USER_MODALS_INFO_2 *info2)
2190 struct samr_DomInfo5 dom_info5;
2192 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2201 NT_STATUS_NOT_OK_RETURN(status);
2203 info2->usrmod2_domain_name =
2204 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2205 info2->usrmod2_domain_id =
2206 (struct domsid *)dom_sid_dup(mem_ctx, domain_sid);
2208 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2209 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2211 return NT_STATUS_OK;
2214 /****************************************************************
2215 ****************************************************************/
2217 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2218 struct rpc_pipe_client *pipe_cli,
2219 struct policy_handle *domain_handle,
2220 struct USER_MODALS_INFO_3 *info3)
2223 struct samr_DomInfo12 dom_info12;
2225 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2234 NT_STATUS_NOT_OK_RETURN(status);
2236 info3->usrmod3_lockout_duration =
2237 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2238 info3->usrmod3_lockout_observation_window =
2239 nt_time_to_unix_abs(&dom_info12.lockout_window);
2240 info3->usrmod3_lockout_threshold =
2241 dom_info12.lockout_threshold;
2243 return NT_STATUS_OK;
2246 /****************************************************************
2247 ****************************************************************/
2249 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2250 struct rpc_pipe_client *pipe_cli,
2252 struct policy_handle *domain_handle,
2253 struct dom_sid *domain_sid,
2258 struct USER_MODALS_INFO_0 info0;
2259 struct USER_MODALS_INFO_1 info1;
2260 struct USER_MODALS_INFO_2 info2;
2261 struct USER_MODALS_INFO_3 info3;
2264 return ERROR_INSUFFICIENT_BUFFER;
2269 status = query_USER_MODALS_INFO_0(mem_ctx,
2273 NT_STATUS_NOT_OK_RETURN(status);
2275 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2280 status = query_USER_MODALS_INFO_1(mem_ctx,
2284 NT_STATUS_NOT_OK_RETURN(status);
2286 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2290 status = query_USER_MODALS_INFO_2(mem_ctx,
2295 NT_STATUS_NOT_OK_RETURN(status);
2297 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2301 status = query_USER_MODALS_INFO_3(mem_ctx,
2305 NT_STATUS_NOT_OK_RETURN(status);
2307 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2314 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2316 return NT_STATUS_OK;
2319 /****************************************************************
2320 ****************************************************************/
2322 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2323 struct NetUserModalsGet *r)
2325 struct rpc_pipe_client *pipe_cli = NULL;
2329 struct policy_handle connect_handle, domain_handle;
2330 struct dom_sid2 *domain_sid = NULL;
2331 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2333 ZERO_STRUCT(connect_handle);
2334 ZERO_STRUCT(domain_handle);
2336 if (!r->out.buffer) {
2337 return WERR_INVALID_PARAM;
2340 switch (r->in.level) {
2342 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2343 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2347 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2350 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2353 werr = WERR_UNKNOWN_LEVEL;
2357 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2358 &ndr_table_samr.syntax_id,
2360 if (!W_ERROR_IS_OK(werr)) {
2364 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2365 SAMR_ACCESS_ENUM_DOMAINS |
2366 SAMR_ACCESS_LOOKUP_DOMAIN,
2371 if (!W_ERROR_IS_OK(werr)) {
2378 /* 3: 12 (DomainInfo2) */
2380 status = query_USER_MODALS_INFO_to_buffer(ctx,
2386 if (!NT_STATUS_IS_OK(status)) {
2387 werr = ntstatus_to_werror(status);
2392 if (ctx->disable_policy_handle_cache) {
2393 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2394 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2400 /****************************************************************
2401 ****************************************************************/
2403 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2404 struct NetUserModalsGet *r)
2406 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2409 /****************************************************************
2410 ****************************************************************/
2412 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2413 struct rpc_pipe_client *pipe_cli,
2414 struct policy_handle *domain_handle,
2415 struct samr_DomInfo1 *info1,
2416 struct samr_DomInfo3 *info3,
2417 struct samr_DomInfo12 *info12)
2419 NTSTATUS status, result;
2420 union samr_DomainInfo dom_info;
2421 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2425 ZERO_STRUCT(dom_info);
2427 dom_info.info1 = *info1;
2429 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2434 NT_STATUS_NOT_OK_RETURN(status);
2435 NT_STATUS_NOT_OK_RETURN(result);
2440 ZERO_STRUCT(dom_info);
2442 dom_info.info3 = *info3;
2444 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2450 NT_STATUS_NOT_OK_RETURN(status);
2451 NT_STATUS_NOT_OK_RETURN(result);
2456 ZERO_STRUCT(dom_info);
2458 dom_info.info12 = *info12;
2460 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2466 NT_STATUS_NOT_OK_RETURN(status);
2467 NT_STATUS_NOT_OK_RETURN(result);
2470 return NT_STATUS_OK;
2473 /****************************************************************
2474 ****************************************************************/
2476 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2477 struct rpc_pipe_client *pipe_cli,
2478 struct policy_handle *domain_handle,
2479 struct USER_MODALS_INFO_0 *info0)
2482 struct samr_DomInfo1 dom_info_1;
2483 struct samr_DomInfo3 dom_info_3;
2485 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2494 NT_STATUS_NOT_OK_RETURN(status);
2496 dom_info_1.min_password_length =
2497 info0->usrmod0_min_passwd_len;
2498 dom_info_1.password_history_length =
2499 info0->usrmod0_password_hist_len;
2501 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2502 info0->usrmod0_max_passwd_age);
2503 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2504 info0->usrmod0_min_passwd_age);
2506 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2507 info0->usrmod0_force_logoff);
2509 return set_USER_MODALS_INFO_rpc(mem_ctx,
2517 /****************************************************************
2518 ****************************************************************/
2520 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2521 struct rpc_pipe_client *pipe_cli,
2522 struct policy_handle *domain_handle,
2523 struct USER_MODALS_INFO_3 *info3)
2526 struct samr_DomInfo12 dom_info_12;
2528 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2537 NT_STATUS_NOT_OK_RETURN(status);
2539 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2540 info3->usrmod3_lockout_duration);
2541 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2542 info3->usrmod3_lockout_observation_window);
2543 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2545 return set_USER_MODALS_INFO_rpc(mem_ctx,
2553 /****************************************************************
2554 ****************************************************************/
2556 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2557 struct rpc_pipe_client *pipe_cli,
2558 struct policy_handle *domain_handle,
2559 struct USER_MODALS_INFO_1001 *info1001)
2562 struct samr_DomInfo1 dom_info_1;
2564 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2573 NT_STATUS_NOT_OK_RETURN(status);
2575 dom_info_1.min_password_length =
2576 info1001->usrmod1001_min_passwd_len;
2578 return set_USER_MODALS_INFO_rpc(mem_ctx,
2586 /****************************************************************
2587 ****************************************************************/
2589 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2590 struct rpc_pipe_client *pipe_cli,
2591 struct policy_handle *domain_handle,
2592 struct USER_MODALS_INFO_1002 *info1002)
2595 struct samr_DomInfo1 dom_info_1;
2597 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2606 NT_STATUS_NOT_OK_RETURN(status);
2608 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2609 info1002->usrmod1002_max_passwd_age);
2611 return set_USER_MODALS_INFO_rpc(mem_ctx,
2619 /****************************************************************
2620 ****************************************************************/
2622 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2623 struct rpc_pipe_client *pipe_cli,
2624 struct policy_handle *domain_handle,
2625 struct USER_MODALS_INFO_1003 *info1003)
2628 struct samr_DomInfo1 dom_info_1;
2630 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2639 NT_STATUS_NOT_OK_RETURN(status);
2641 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2642 info1003->usrmod1003_min_passwd_age);
2644 return set_USER_MODALS_INFO_rpc(mem_ctx,
2652 /****************************************************************
2653 ****************************************************************/
2655 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2656 struct rpc_pipe_client *pipe_cli,
2657 struct policy_handle *domain_handle,
2658 struct USER_MODALS_INFO_1004 *info1004)
2661 struct samr_DomInfo3 dom_info_3;
2663 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2672 NT_STATUS_NOT_OK_RETURN(status);
2674 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2675 info1004->usrmod1004_force_logoff);
2677 return set_USER_MODALS_INFO_rpc(mem_ctx,
2685 /****************************************************************
2686 ****************************************************************/
2688 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2689 struct rpc_pipe_client *pipe_cli,
2690 struct policy_handle *domain_handle,
2691 struct USER_MODALS_INFO_1005 *info1005)
2694 struct samr_DomInfo1 dom_info_1;
2696 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2705 NT_STATUS_NOT_OK_RETURN(status);
2707 dom_info_1.password_history_length =
2708 info1005->usrmod1005_password_hist_len;
2710 return set_USER_MODALS_INFO_rpc(mem_ctx,
2718 /****************************************************************
2719 ****************************************************************/
2721 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2722 struct rpc_pipe_client *pipe_cli,
2724 struct policy_handle *domain_handle,
2725 struct dom_sid *domain_sid,
2728 struct USER_MODALS_INFO_0 *info0;
2729 struct USER_MODALS_INFO_3 *info3;
2730 struct USER_MODALS_INFO_1001 *info1001;
2731 struct USER_MODALS_INFO_1002 *info1002;
2732 struct USER_MODALS_INFO_1003 *info1003;
2733 struct USER_MODALS_INFO_1004 *info1004;
2734 struct USER_MODALS_INFO_1005 *info1005;
2737 return ERROR_INSUFFICIENT_BUFFER;
2742 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2743 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2748 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2749 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2754 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2755 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2760 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2761 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2766 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2767 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2772 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2773 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2778 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2779 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2788 return NT_STATUS_OK;
2791 /****************************************************************
2792 ****************************************************************/
2794 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2795 struct NetUserModalsSet *r)
2797 struct rpc_pipe_client *pipe_cli = NULL;
2801 struct policy_handle connect_handle, domain_handle;
2802 struct dom_sid2 *domain_sid = NULL;
2803 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2805 ZERO_STRUCT(connect_handle);
2806 ZERO_STRUCT(domain_handle);
2808 if (!r->in.buffer) {
2809 return WERR_INVALID_PARAM;
2812 switch (r->in.level) {
2814 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2815 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2816 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2817 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2824 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2825 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2828 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2829 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2835 werr = WERR_NOT_SUPPORTED;
2838 werr = WERR_UNKNOWN_LEVEL;
2842 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2843 &ndr_table_samr.syntax_id,
2845 if (!W_ERROR_IS_OK(werr)) {
2849 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2850 SAMR_ACCESS_ENUM_DOMAINS |
2851 SAMR_ACCESS_LOOKUP_DOMAIN,
2856 if (!W_ERROR_IS_OK(werr)) {
2860 status = set_USER_MODALS_INFO_buffer(ctx,
2866 if (!NT_STATUS_IS_OK(status)) {
2867 werr = ntstatus_to_werror(status);
2872 if (ctx->disable_policy_handle_cache) {
2873 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2874 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2880 /****************************************************************
2881 ****************************************************************/
2883 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2884 struct NetUserModalsSet *r)
2886 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2889 /****************************************************************
2890 ****************************************************************/
2892 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2894 const char *group_name,
2895 uint32_t attributes,
2897 uint32_t *num_entries)
2899 struct GROUP_USERS_INFO_0 u0;
2900 struct GROUP_USERS_INFO_1 u1;
2905 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2906 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2908 u0.grui0_name = NULL;
2911 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2912 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2916 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2917 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2919 u1.grui1_name = NULL;
2922 u1.grui1_attributes = attributes;
2924 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2925 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2928 return NT_STATUS_INVALID_INFO_CLASS;
2931 return NT_STATUS_OK;
2934 /****************************************************************
2935 ****************************************************************/
2937 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2938 struct NetUserGetGroups *r)
2940 struct rpc_pipe_client *pipe_cli = NULL;
2941 struct policy_handle connect_handle, domain_handle, user_handle;
2942 struct lsa_String lsa_account_name;
2943 struct dom_sid2 *domain_sid = NULL;
2944 struct samr_Ids user_rids, name_types;
2945 struct samr_RidWithAttributeArray *rid_array = NULL;
2946 struct lsa_Strings names;
2947 struct samr_Ids types;
2948 uint32_t *rids = NULL;
2951 uint32_t entries_read = 0;
2953 NTSTATUS status = NT_STATUS_OK;
2954 NTSTATUS result = NT_STATUS_OK;
2956 struct dcerpc_binding_handle *b = NULL;
2958 ZERO_STRUCT(connect_handle);
2959 ZERO_STRUCT(domain_handle);
2961 if (!r->out.buffer) {
2962 return WERR_INVALID_PARAM;
2965 *r->out.buffer = NULL;
2966 *r->out.entries_read = 0;
2967 *r->out.total_entries = 0;
2969 switch (r->in.level) {
2974 return WERR_UNKNOWN_LEVEL;
2977 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2978 &ndr_table_samr.syntax_id,
2980 if (!W_ERROR_IS_OK(werr)) {
2984 b = pipe_cli->binding_handle;
2986 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2987 SAMR_ACCESS_ENUM_DOMAINS |
2988 SAMR_ACCESS_LOOKUP_DOMAIN,
2989 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2993 if (!W_ERROR_IS_OK(werr)) {
2997 init_lsa_String(&lsa_account_name, r->in.user_name);
2999 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3006 if (!NT_STATUS_IS_OK(status)) {
3007 werr = ntstatus_to_werror(status);
3010 if (!NT_STATUS_IS_OK(result)) {
3011 werr = ntstatus_to_werror(result);
3015 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3017 SAMR_USER_ACCESS_GET_GROUPS,
3021 if (!NT_STATUS_IS_OK(status)) {
3022 werr = ntstatus_to_werror(status);
3025 if (!NT_STATUS_IS_OK(result)) {
3026 werr = ntstatus_to_werror(result);
3030 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3034 if (!NT_STATUS_IS_OK(status)) {
3035 werr = ntstatus_to_werror(status);
3038 if (!NT_STATUS_IS_OK(result)) {
3039 werr = ntstatus_to_werror(result);
3043 rids = talloc_array(ctx, uint32_t, rid_array->count);
3049 for (i=0; i < rid_array->count; i++) {
3050 rids[i] = rid_array->rids[i].rid;
3053 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3060 if (!NT_STATUS_IS_OK(status)) {
3061 werr = ntstatus_to_werror(status);
3064 if (!NT_STATUS_IS_OK(result) &&
3065 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3066 werr = ntstatus_to_werror(result);
3070 for (i=0; i < names.count; i++) {
3071 status = add_GROUP_USERS_INFO_X_buffer(ctx,
3073 names.names[i].string,
3074 rid_array->rids[i].attributes,
3077 if (!NT_STATUS_IS_OK(status)) {
3078 werr = ntstatus_to_werror(status);
3083 *r->out.entries_read = entries_read;
3084 *r->out.total_entries = entries_read;
3087 if (ctx->disable_policy_handle_cache) {
3088 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3089 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3095 /****************************************************************
3096 ****************************************************************/
3098 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
3099 struct NetUserGetGroups *r)
3101 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
3104 /****************************************************************
3105 ****************************************************************/
3107 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
3108 struct NetUserSetGroups *r)
3110 struct rpc_pipe_client *pipe_cli = NULL;
3111 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
3112 struct lsa_String lsa_account_name;
3113 struct dom_sid2 *domain_sid = NULL;
3114 struct samr_Ids user_rids, name_types;
3115 struct samr_Ids group_rids;
3116 struct samr_RidWithAttributeArray *rid_array = NULL;
3117 struct lsa_String *lsa_names = NULL;
3119 uint32_t *add_rids = NULL;
3120 uint32_t *del_rids = NULL;
3121 size_t num_add_rids = 0;
3122 size_t num_del_rids = 0;
3124 uint32_t *member_rids = NULL;
3125 size_t num_member_rids = 0;
3127 struct GROUP_USERS_INFO_0 *i0 = NULL;
3128 struct GROUP_USERS_INFO_1 *i1 = NULL;
3132 NTSTATUS status = NT_STATUS_OK;
3133 NTSTATUS result = NT_STATUS_OK;
3135 struct dcerpc_binding_handle *b = NULL;
3137 ZERO_STRUCT(connect_handle);
3138 ZERO_STRUCT(domain_handle);
3140 if (!r->in.buffer) {
3141 return WERR_INVALID_PARAM;
3144 switch (r->in.level) {
3149 return WERR_UNKNOWN_LEVEL;
3152 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3153 &ndr_table_samr.syntax_id,
3155 if (!W_ERROR_IS_OK(werr)) {
3159 b = pipe_cli->binding_handle;
3161 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3162 SAMR_ACCESS_ENUM_DOMAINS |
3163 SAMR_ACCESS_LOOKUP_DOMAIN,
3164 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3168 if (!W_ERROR_IS_OK(werr)) {
3172 init_lsa_String(&lsa_account_name, r->in.user_name);
3174 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3181 if (!NT_STATUS_IS_OK(status)) {
3182 werr = ntstatus_to_werror(status);
3185 if (!NT_STATUS_IS_OK(result)) {
3186 werr = ntstatus_to_werror(result);
3190 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3192 SAMR_USER_ACCESS_GET_GROUPS,
3196 if (!NT_STATUS_IS_OK(status)) {
3197 werr = ntstatus_to_werror(status);
3200 if (!NT_STATUS_IS_OK(result)) {
3201 werr = ntstatus_to_werror(result);
3205 switch (r->in.level) {
3207 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3210 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3214 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3220 for (i=0; i < r->in.num_entries; i++) {
3222 switch (r->in.level) {
3224 init_lsa_String(&lsa_names[i], i0->grui0_name);
3228 init_lsa_String(&lsa_names[i], i1->grui1_name);
3234 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3241 if (!NT_STATUS_IS_OK(status)) {
3242 werr = ntstatus_to_werror(status);
3245 if (!NT_STATUS_IS_OK(result)) {
3246 werr = ntstatus_to_werror(result);
3250 member_rids = group_rids.ids;
3251 num_member_rids = group_rids.count;
3253 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3257 if (!NT_STATUS_IS_OK(status)) {
3258 werr = ntstatus_to_werror(status);
3261 if (!NT_STATUS_IS_OK(result)) {
3262 werr = ntstatus_to_werror(result);
3268 for (i=0; i < r->in.num_entries; i++) {
3269 bool already_member = false;
3270 for (k=0; k < rid_array->count; k++) {
3271 if (member_rids[i] == rid_array->rids[k].rid) {
3272 already_member = true;
3276 if (!already_member) {
3277 if (!add_rid_to_array_unique(ctx,
3279 &add_rids, &num_add_rids)) {
3280 werr = WERR_GENERAL_FAILURE;
3288 for (k=0; k < rid_array->count; k++) {
3289 bool keep_member = false;
3290 for (i=0; i < r->in.num_entries; i++) {
3291 if (member_rids[i] == rid_array->rids[k].rid) {
3297 if (!add_rid_to_array_unique(ctx,
3298 rid_array->rids[k].rid,
3299 &del_rids, &num_del_rids)) {
3300 werr = WERR_GENERAL_FAILURE;
3308 for (i=0; i < num_add_rids; i++) {
3309 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3311 SAMR_GROUP_ACCESS_ADD_MEMBER,
3315 if (!NT_STATUS_IS_OK(status)) {
3316 werr = ntstatus_to_werror(status);
3319 if (!NT_STATUS_IS_OK(result)) {
3320 werr = ntstatus_to_werror(result);
3324 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
3329 if (!NT_STATUS_IS_OK(status)) {
3330 werr = ntstatus_to_werror(status);
3333 if (!NT_STATUS_IS_OK(result)) {
3334 werr = ntstatus_to_werror(result);
3338 if (is_valid_policy_hnd(&group_handle)) {
3339 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3345 for (i=0; i < num_del_rids; i++) {
3346 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3348 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3352 if (!NT_STATUS_IS_OK(status)) {
3353 werr = ntstatus_to_werror(status);
3356 if (!NT_STATUS_IS_OK(result)) {
3357 werr = ntstatus_to_werror(result);
3361 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
3365 if (!NT_STATUS_IS_OK(status)) {
3366 werr = ntstatus_to_werror(status);
3369 if (!NT_STATUS_IS_OK(result)) {
3370 werr = ntstatus_to_werror(result);
3374 if (is_valid_policy_hnd(&group_handle)) {
3375 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3382 if (is_valid_policy_hnd(&group_handle)) {
3383 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3386 if (ctx->disable_policy_handle_cache) {
3387 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3388 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3394 /****************************************************************
3395 ****************************************************************/
3397 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3398 struct NetUserSetGroups *r)
3400 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3403 /****************************************************************
3404 ****************************************************************/
3406 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3408 const char *group_name,
3410 uint32_t *num_entries)
3412 struct LOCALGROUP_USERS_INFO_0 u0;
3416 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3417 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3419 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3420 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3423 return NT_STATUS_INVALID_INFO_CLASS;
3426 return NT_STATUS_OK;
3429 /****************************************************************
3430 ****************************************************************/
3432 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3433 struct NetUserGetLocalGroups *r)
3435 struct rpc_pipe_client *pipe_cli = NULL;
3436 struct policy_handle connect_handle, domain_handle, user_handle,
3438 struct lsa_String lsa_account_name;
3439 struct dom_sid2 *domain_sid = NULL;
3440 struct samr_Ids user_rids, name_types;
3441 struct samr_RidWithAttributeArray *rid_array = NULL;
3442 struct lsa_Strings names;
3443 struct samr_Ids types;
3444 uint32_t *rids = NULL;
3445 size_t num_rids = 0;
3446 struct dom_sid user_sid;
3447 struct lsa_SidArray sid_array;
3448 struct samr_Ids domain_rids;
3449 struct samr_Ids builtin_rids;
3452 uint32_t entries_read = 0;
3454 NTSTATUS status = NT_STATUS_OK;
3455 NTSTATUS result = NT_STATUS_OK;
3457 struct dcerpc_binding_handle *b = NULL;
3459 ZERO_STRUCT(connect_handle);
3460 ZERO_STRUCT(domain_handle);
3462 if (!r->out.buffer) {
3463 return WERR_INVALID_PARAM;
3466 *r->out.buffer = NULL;
3467 *r->out.entries_read = 0;
3468 *r->out.total_entries = 0;
3470 switch (r->in.level) {
3475 return WERR_UNKNOWN_LEVEL;
3478 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3479 &ndr_table_samr.syntax_id,
3481 if (!W_ERROR_IS_OK(werr)) {
3485 b = pipe_cli->binding_handle;
3487 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3488 SAMR_ACCESS_ENUM_DOMAINS |
3489 SAMR_ACCESS_LOOKUP_DOMAIN,
3490 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3491 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3495 if (!W_ERROR_IS_OK(werr)) {
3499 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3500 SAMR_ACCESS_ENUM_DOMAINS |
3501 SAMR_ACCESS_LOOKUP_DOMAIN,
3502 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3503 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3506 if (!W_ERROR_IS_OK(werr)) {
3510 init_lsa_String(&lsa_account_name, r->in.user_name);
3512 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3519 if (!NT_STATUS_IS_OK(status)) {
3520 werr = ntstatus_to_werror(status);
3523 if (!NT_STATUS_IS_OK(result)) {
3524 werr = ntstatus_to_werror(result);
3528 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3530 SAMR_USER_ACCESS_GET_GROUPS,
3534 if (!NT_STATUS_IS_OK(status)) {
3535 werr = ntstatus_to_werror(status);
3538 if (!NT_STATUS_IS_OK(result)) {
3539 werr = ntstatus_to_werror(result);
3543 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3547 if (!NT_STATUS_IS_OK(status)) {
3548 werr = ntstatus_to_werror(status);
3551 if (!NT_STATUS_IS_OK(result)) {
3552 werr = ntstatus_to_werror(result);
3556 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3561 sid_array.num_sids = rid_array->count + 1;
3562 sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
3563 if (!sid_array.sids) {
3568 sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid);
3569 if (!sid_array.sids[0].sid) {
3574 for (i=0; i < rid_array->count; i++) {
3577 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3582 sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid);
3583 if (!sid_array.sids[i+1].sid) {
3589 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3594 if (!NT_STATUS_IS_OK(status)) {
3595 werr = ntstatus_to_werror(status);
3598 if (!NT_STATUS_IS_OK(result)) {
3599 werr = ntstatus_to_werror(result);
3603 for (i=0; i < domain_rids.count; i++) {
3604 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3605 &rids, &num_rids)) {
3611 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3616 if (!NT_STATUS_IS_OK(status)) {
3617 werr = ntstatus_to_werror(status);
3620 if (!NT_STATUS_IS_OK(result)) {
3621 werr = ntstatus_to_werror(result);
3625 for (i=0; i < builtin_rids.count; i++) {
3626 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3627 &rids, &num_rids)) {
3633 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3640 if (!NT_STATUS_IS_OK(status)) {
3641 werr = ntstatus_to_werror(status);
3644 if (!NT_STATUS_IS_OK(result)) {
3645 werr = ntstatus_to_werror(result);
3649 for (i=0; i < names.count; i++) {
3650 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3652 names.names[i].string,
3655 if (!NT_STATUS_IS_OK(status)) {
3656 werr = ntstatus_to_werror(status);
3661 *r->out.entries_read = entries_read;
3662 *r->out.total_entries = entries_read;
3665 if (ctx->disable_policy_handle_cache) {
3666 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3667 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3673 /****************************************************************
3674 ****************************************************************/
3676 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3677 struct NetUserGetLocalGroups *r)
3679 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);