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