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_EXPIRED_FLAG
;
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
*mem_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 status
= init_samr_CryptPasswordEx(uX
->usriX_password
,
318 &user_info
.info25
.password
);
319 if (!NT_STATUS_IS_OK(status
)) {
323 status
= dcerpc_samr_SetUserInfo2(b
, mem_ctx
,
328 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
)) {
330 user_info
.info23
.info
= info21
;
332 status
= init_samr_CryptPassword(uX
->usriX_password
,
334 &user_info
.info23
.password
);
335 if (!NT_STATUS_IS_OK(status
)) {
339 status
= dcerpc_samr_SetUserInfo2(b
, mem_ctx
,
344 if (!NT_STATUS_IS_OK(status
)) {
349 if (!NT_STATUS_IS_OK(status
)) {
354 user_info
.info21
= info21
;
356 status
= dcerpc_samr_SetUserInfo(b
, mem_ctx
,
361 if (!NT_STATUS_IS_OK(status
)) {
369 /****************************************************************
370 ****************************************************************/
372 WERROR
NetUserAdd_r(struct libnetapi_ctx
*ctx
,
373 struct NetUserAdd
*r
)
375 struct rpc_pipe_client
*pipe_cli
= NULL
;
376 NTSTATUS status
, result
;
378 struct policy_handle connect_handle
, domain_handle
, user_handle
;
379 struct lsa_String lsa_account_name
;
380 struct dom_sid2
*domain_sid
= NULL
;
381 union samr_UserInfo
*user_info
= NULL
;
382 struct samr_PwInfo pw_info
;
383 uint32_t access_granted
= 0;
385 struct USER_INFO_X uX
;
386 struct dcerpc_binding_handle
*b
= NULL
;
387 DATA_BLOB session_key
;
389 ZERO_STRUCT(connect_handle
);
390 ZERO_STRUCT(domain_handle
);
391 ZERO_STRUCT(user_handle
);
394 return WERR_INVALID_PARAMETER
;
397 switch (r
->in
.level
) {
404 werr
= WERR_NOT_SUPPORTED
;
408 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
411 if (!W_ERROR_IS_OK(werr
)) {
415 b
= pipe_cli
->binding_handle
;
417 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
418 if (!NT_STATUS_IS_OK(status
)) {
419 werr
= ntstatus_to_werror(status
);
423 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
424 SAMR_ACCESS_ENUM_DOMAINS
|
425 SAMR_ACCESS_LOOKUP_DOMAIN
,
426 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
427 SAMR_DOMAIN_ACCESS_CREATE_USER
|
428 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
432 if (!W_ERROR_IS_OK(werr
)) {
436 init_lsa_String(&lsa_account_name
, uX
.usriX_name
);
438 status
= dcerpc_samr_CreateUser2(b
, talloc_tos(),
444 SAMR_USER_ACCESS_SET_PASSWORD
|
445 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
446 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
451 if (any_nt_status_not_ok(status
, result
, &status
)) {
452 werr
= ntstatus_to_werror(status
);
456 status
= dcerpc_samr_QueryUserInfo(b
, talloc_tos(),
461 if (any_nt_status_not_ok(status
, result
, &status
)) {
462 werr
= ntstatus_to_werror(status
);
466 if (!(user_info
->info16
.acct_flags
& ACB_NORMAL
)) {
467 werr
= WERR_INVALID_PARAMETER
;
471 status
= dcerpc_samr_GetUserPwInfo(b
, talloc_tos(),
475 if (any_nt_status_not_ok(status
, result
, &status
)) {
476 werr
= ntstatus_to_werror(status
);
480 status
= dcerpc_binding_handle_transport_session_key(
481 b
, talloc_tos(), &session_key
);
482 if (!NT_STATUS_IS_OK(status
)) {
483 werr
= ntstatus_to_werror(status
);
487 uX
.usriX_flags
|= ACB_NORMAL
;
489 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
493 if (!NT_STATUS_IS_OK(status
)) {
494 werr
= ntstatus_to_werror(status
);
502 dcerpc_samr_DeleteUser(b
, talloc_tos(),
507 if (is_valid_policy_hnd(&user_handle
) && b
) {
508 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
511 if (ctx
->disable_policy_handle_cache
) {
512 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
513 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
519 /****************************************************************
520 ****************************************************************/
522 WERROR
NetUserAdd_l(struct libnetapi_ctx
*ctx
,
523 struct NetUserAdd
*r
)
525 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserAdd
);
528 /****************************************************************
529 ****************************************************************/
531 WERROR
NetUserDel_r(struct libnetapi_ctx
*ctx
,
532 struct NetUserDel
*r
)
534 struct rpc_pipe_client
*pipe_cli
= NULL
;
535 NTSTATUS status
, result
;
537 struct policy_handle connect_handle
, builtin_handle
, domain_handle
, user_handle
;
538 struct lsa_String lsa_account_name
;
539 struct samr_Ids user_rids
, name_types
;
540 struct dom_sid2
*domain_sid
= NULL
;
541 struct dom_sid2 user_sid
;
542 struct dcerpc_binding_handle
*b
= NULL
;
544 ZERO_STRUCT(connect_handle
);
545 ZERO_STRUCT(builtin_handle
);
546 ZERO_STRUCT(domain_handle
);
547 ZERO_STRUCT(user_handle
);
549 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
553 if (!W_ERROR_IS_OK(werr
)) {
557 b
= pipe_cli
->binding_handle
;
559 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
560 SAMR_ACCESS_ENUM_DOMAINS
|
561 SAMR_ACCESS_LOOKUP_DOMAIN
,
562 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
566 if (!W_ERROR_IS_OK(werr
)) {
570 status
= dcerpc_samr_OpenDomain(b
, talloc_tos(),
572 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
573 discard_const_p(struct dom_sid
, &global_sid_Builtin
),
576 if (any_nt_status_not_ok(status
, result
, &status
)) {
577 werr
= ntstatus_to_werror(status
);
581 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
583 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
590 if (any_nt_status_not_ok(status
, result
, &status
)) {
591 werr
= ntstatus_to_werror(status
);
594 if (user_rids
.count
!= 1) {
595 werr
= WERR_BAD_NET_RESP
;
598 if (name_types
.count
!= 1) {
599 werr
= WERR_BAD_NET_RESP
;
603 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
609 if (any_nt_status_not_ok(status
, result
, &status
)) {
610 werr
= ntstatus_to_werror(status
);
614 sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0]);
616 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, talloc_tos(),
620 if (any_nt_status_not_ok(status
, result
, &status
)) {
621 werr
= ntstatus_to_werror(status
);
625 status
= dcerpc_samr_DeleteUser(b
, talloc_tos(),
628 if (any_nt_status_not_ok(status
, result
, &status
)) {
629 werr
= ntstatus_to_werror(status
);
636 if (is_valid_policy_hnd(&user_handle
)) {
637 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
640 if (ctx
->disable_policy_handle_cache
) {
641 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
642 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
643 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
649 /****************************************************************
650 ****************************************************************/
652 WERROR
NetUserDel_l(struct libnetapi_ctx
*ctx
,
653 struct NetUserDel
*r
)
655 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserDel
);
658 /****************************************************************
659 ****************************************************************/
661 static NTSTATUS
libnetapi_samr_lookup_user(TALLOC_CTX
*mem_ctx
,
662 struct rpc_pipe_client
*pipe_cli
,
663 struct policy_handle
*domain_handle
,
664 struct policy_handle
*builtin_handle
,
665 const char *user_name
,
666 const struct dom_sid
*domain_sid
,
669 struct samr_UserInfo21
**info21
,
670 struct sec_desc_buf
**sec_desc
,
671 uint32_t *auth_flag_p
)
673 NTSTATUS status
, result
;
675 struct policy_handle user_handle
;
676 union samr_UserInfo
*user_info
= NULL
;
677 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
678 uint32_t access_mask
= SEC_STD_READ_CONTROL
|
679 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
680 SAMR_USER_ACCESS_GET_NAME_ETC
;
681 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
683 ZERO_STRUCT(user_handle
);
689 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
690 SAMR_USER_ACCESS_GET_GROUPS
;
696 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
697 SAMR_USER_ACCESS_GET_GROUPS
|
698 SAMR_USER_ACCESS_GET_LOCALE
;
705 return NT_STATUS_INVALID_LEVEL
;
712 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
718 if (any_nt_status_not_ok(status
, result
, &status
)) {
722 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
727 if (any_nt_status_not_ok(status
, result
, &status
)) {
731 status
= dcerpc_samr_QuerySecurity(b
, mem_ctx
,
736 if (any_nt_status_not_ok(status
, result
, &status
)) {
740 if (access_mask
& SAMR_USER_ACCESS_GET_GROUPS
) {
742 struct lsa_SidArray sid_array
;
743 struct samr_Ids alias_rids
;
745 uint32_t auth_flag
= 0;
748 status
= dcerpc_samr_GetGroupsForUser(b
, mem_ctx
,
752 if (any_nt_status_not_ok(status
, result
, &status
)) {
756 sid_array
.num_sids
= rid_array
->count
+ 1;
757 sid_array
.sids
= talloc_array(mem_ctx
, struct lsa_SidPtr
,
759 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
);
761 for (i
=0; i
<rid_array
->count
; i
++) {
762 sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
);
763 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
764 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
767 sid_compose(&sid
, domain_sid
, rid
);
768 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
769 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
771 status
= dcerpc_samr_GetAliasMembership(b
, mem_ctx
,
776 if (any_nt_status_not_ok(status
, result
, &status
)) {
780 for (i
=0; i
<alias_rids
.count
; i
++) {
781 switch (alias_rids
.ids
[i
]) {
782 case 550: /* Print Operators */
783 auth_flag
|= AF_OP_PRINT
;
785 case 549: /* Server Operators */
786 auth_flag
|= AF_OP_SERVER
;
788 case 548: /* Account Operators */
789 auth_flag
|= AF_OP_ACCOUNTS
;
797 *auth_flag_p
= auth_flag
;
801 *info21
= &user_info
->info21
;
804 if (is_valid_policy_hnd(&user_handle
)) {
805 dcerpc_samr_Close(b
, mem_ctx
, &user_handle
, &result
);
811 /****************************************************************
812 ****************************************************************/
814 static uint32_t samr_rid_to_priv_level(uint32_t rid
)
817 case DOMAIN_RID_ADMINISTRATOR
:
818 return USER_PRIV_ADMIN
;
819 case DOMAIN_RID_GUEST
:
820 return USER_PRIV_GUEST
;
822 return USER_PRIV_USER
;
826 /****************************************************************
827 ****************************************************************/
829 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb
)
831 uint32_t fl
= UF_SCRIPT
; /* god knows why */
833 fl
|= ds_acb2uf(acb
);
838 /****************************************************************
839 ****************************************************************/
841 static NTSTATUS
info21_to_USER_INFO_1(TALLOC_CTX
*mem_ctx
,
842 const struct samr_UserInfo21
*i21
,
843 struct USER_INFO_1
*i
)
846 i
->usri1_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
847 NT_STATUS_HAVE_NO_MEMORY(i
->usri1_name
);
848 i
->usri1_password
= NULL
;
849 i
->usri1_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
850 i
->usri1_priv
= samr_rid_to_priv_level(i21
->rid
);
851 i
->usri1_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
852 i
->usri1_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
853 i
->usri1_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
854 i
->usri1_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
859 /****************************************************************
860 ****************************************************************/
862 static NTSTATUS
info21_to_USER_INFO_2(TALLOC_CTX
*mem_ctx
,
863 const struct samr_UserInfo21
*i21
,
865 struct USER_INFO_2
*i
)
869 i
->usri2_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
870 NT_STATUS_HAVE_NO_MEMORY(i
->usri2_name
);
871 i
->usri2_password
= NULL
;
872 i
->usri2_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
873 i
->usri2_priv
= samr_rid_to_priv_level(i21
->rid
);
874 i
->usri2_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
875 i
->usri2_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
876 i
->usri2_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
877 i
->usri2_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
878 i
->usri2_auth_flags
= auth_flag
;
879 i
->usri2_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
880 i
->usri2_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
881 i
->usri2_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
882 i
->usri2_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
883 i
->usri2_last_logon
= nt_time_to_unix(i21
->last_logon
);
884 i
->usri2_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
885 i
->usri2_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
886 i
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
887 i
->usri2_units_per_week
= i21
->logon_hours
.units_per_week
;
888 i
->usri2_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
889 i
->usri2_bad_pw_count
= i21
->bad_password_count
;
890 i
->usri2_num_logons
= i21
->logon_count
;
891 i
->usri2_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
892 i
->usri2_country_code
= i21
->country_code
;
893 i
->usri2_code_page
= i21
->code_page
;
898 /****************************************************************
899 ****************************************************************/
901 static NTSTATUS
info21_to_USER_INFO_3(TALLOC_CTX
*mem_ctx
,
902 const struct samr_UserInfo21
*i21
,
904 struct USER_INFO_3
*i
)
908 i
->usri3_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
909 NT_STATUS_HAVE_NO_MEMORY(i
->usri3_name
);
910 i
->usri3_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
911 i
->usri3_priv
= samr_rid_to_priv_level(i21
->rid
);
912 i
->usri3_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
913 i
->usri3_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
914 i
->usri3_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
915 i
->usri3_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
916 i
->usri3_auth_flags
= auth_flag
;
917 i
->usri3_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
918 i
->usri3_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
919 i
->usri3_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
920 i
->usri3_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
921 i
->usri3_last_logon
= nt_time_to_unix(i21
->last_logon
);
922 i
->usri3_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
923 i
->usri3_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
924 i
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
925 i
->usri3_units_per_week
= i21
->logon_hours
.units_per_week
;
926 i
->usri3_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
927 i
->usri3_bad_pw_count
= i21
->bad_password_count
;
928 i
->usri3_num_logons
= i21
->logon_count
;
929 i
->usri3_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
930 i
->usri3_country_code
= i21
->country_code
;
931 i
->usri3_code_page
= i21
->code_page
;
932 i
->usri3_user_id
= i21
->rid
;
933 i
->usri3_primary_group_id
= i21
->primary_gid
;
934 i
->usri3_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
935 i
->usri3_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
936 i
->usri3_password_expired
= i21
->password_expired
;
941 /****************************************************************
942 ****************************************************************/
944 static NTSTATUS
info21_to_USER_INFO_4(TALLOC_CTX
*mem_ctx
,
945 const struct samr_UserInfo21
*i21
,
947 struct dom_sid
*domain_sid
,
948 struct USER_INFO_4
*i
)
954 i
->usri4_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
955 NT_STATUS_HAVE_NO_MEMORY(i
->usri4_name
);
956 i
->usri4_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
957 i
->usri4_password
= NULL
;
958 i
->usri4_priv
= samr_rid_to_priv_level(i21
->rid
);
959 i
->usri4_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
960 i
->usri4_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
961 i
->usri4_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
962 i
->usri4_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
963 i
->usri4_auth_flags
= auth_flag
;
964 i
->usri4_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
965 i
->usri4_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
966 i
->usri4_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
967 i
->usri4_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
968 i
->usri4_last_logon
= nt_time_to_unix(i21
->last_logon
);
969 i
->usri4_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
970 i
->usri4_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
971 i
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
972 i
->usri4_units_per_week
= i21
->logon_hours
.units_per_week
;
973 i
->usri4_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
974 i
->usri4_bad_pw_count
= i21
->bad_password_count
;
975 i
->usri4_num_logons
= i21
->logon_count
;
976 i
->usri4_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
977 i
->usri4_country_code
= i21
->country_code
;
978 i
->usri4_code_page
= i21
->code_page
;
979 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
980 return NT_STATUS_NO_MEMORY
;
982 i
->usri4_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
983 i
->usri4_primary_group_id
= i21
->primary_gid
;
984 i
->usri4_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
985 i
->usri4_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
986 i
->usri4_password_expired
= i21
->password_expired
;
991 /****************************************************************
992 ****************************************************************/
994 static NTSTATUS
info21_to_USER_INFO_10(TALLOC_CTX
*mem_ctx
,
995 const struct samr_UserInfo21
*i21
,
996 struct USER_INFO_10
*i
)
1000 i
->usri10_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1001 NT_STATUS_HAVE_NO_MEMORY(i
->usri10_name
);
1002 i
->usri10_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1003 i
->usri10_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1004 i
->usri10_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1006 return NT_STATUS_OK
;
1009 /****************************************************************
1010 ****************************************************************/
1012 static NTSTATUS
info21_to_USER_INFO_11(TALLOC_CTX
*mem_ctx
,
1013 const struct samr_UserInfo21
*i21
,
1015 struct USER_INFO_11
*i
)
1019 i
->usri11_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1020 NT_STATUS_HAVE_NO_MEMORY(i
->usri11_name
);
1021 i
->usri11_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1022 i
->usri11_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1023 i
->usri11_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1024 i
->usri11_priv
= samr_rid_to_priv_level(i21
->rid
);
1025 i
->usri11_auth_flags
= auth_flag
;
1026 i
->usri11_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
1027 i
->usri11_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
1028 i
->usri11_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1029 i
->usri11_last_logon
= nt_time_to_unix(i21
->last_logon
);
1030 i
->usri11_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1031 i
->usri11_bad_pw_count
= i21
->bad_password_count
;
1032 i
->usri11_num_logons
= i21
->logon_count
;
1033 i
->usri11_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1034 i
->usri11_country_code
= i21
->country_code
;
1035 i
->usri11_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1036 i
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1037 i
->usri11_units_per_week
= i21
->logon_hours
.units_per_week
;
1038 i
->usri11_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1039 i
->usri11_code_page
= i21
->code_page
;
1041 return NT_STATUS_OK
;
1044 /****************************************************************
1045 ****************************************************************/
1047 static NTSTATUS
info21_to_USER_INFO_20(TALLOC_CTX
*mem_ctx
,
1048 const struct samr_UserInfo21
*i21
,
1049 struct USER_INFO_20
*i
)
1053 i
->usri20_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1054 NT_STATUS_HAVE_NO_MEMORY(i
->usri20_name
);
1055 i
->usri20_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1056 i
->usri20_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1057 i
->usri20_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1058 i
->usri20_user_id
= i21
->rid
;
1060 return NT_STATUS_OK
;
1063 /****************************************************************
1064 ****************************************************************/
1066 static NTSTATUS
info21_to_USER_INFO_23(TALLOC_CTX
*mem_ctx
,
1067 const struct samr_UserInfo21
*i21
,
1068 struct dom_sid
*domain_sid
,
1069 struct USER_INFO_23
*i
)
1075 i
->usri23_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1076 NT_STATUS_HAVE_NO_MEMORY(i
->usri23_name
);
1077 i
->usri23_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1078 i
->usri23_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1079 i
->usri23_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1080 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1081 return NT_STATUS_NO_MEMORY
;
1083 i
->usri23_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1085 return NT_STATUS_OK
;
1088 /****************************************************************
1089 ****************************************************************/
1091 static NTSTATUS
libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX
*mem_ctx
,
1092 struct rpc_pipe_client
*pipe_cli
,
1093 struct dom_sid
*domain_sid
,
1094 struct policy_handle
*domain_handle
,
1095 struct policy_handle
*builtin_handle
,
1096 const char *user_name
,
1100 uint32_t *num_entries
)
1104 struct samr_UserInfo21
*info21
= NULL
;
1105 struct sec_desc_buf
*sec_desc
= NULL
;
1106 uint32_t auth_flag
= 0;
1108 struct USER_INFO_0 info0
;
1109 struct USER_INFO_1 info1
;
1110 struct USER_INFO_2 info2
;
1111 struct USER_INFO_3 info3
;
1112 struct USER_INFO_4 info4
;
1113 struct USER_INFO_10 info10
;
1114 struct USER_INFO_11 info11
;
1115 struct USER_INFO_20 info20
;
1116 struct USER_INFO_23 info23
;
1130 return NT_STATUS_INVALID_LEVEL
;
1134 info0
.usri0_name
= talloc_strdup(mem_ctx
, user_name
);
1135 NT_STATUS_HAVE_NO_MEMORY(info0
.usri0_name
);
1137 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_0
, info0
,
1138 (struct USER_INFO_0
**)buffer
, num_entries
);
1140 return NT_STATUS_OK
;
1143 status
= libnetapi_samr_lookup_user(mem_ctx
, pipe_cli
,
1154 if (!NT_STATUS_IS_OK(status
)) {
1160 status
= info21_to_USER_INFO_1(mem_ctx
, info21
, &info1
);
1161 NT_STATUS_NOT_OK_RETURN(status
);
1163 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_1
, info1
,
1164 (struct USER_INFO_1
**)buffer
, num_entries
);
1168 status
= info21_to_USER_INFO_2(mem_ctx
, info21
, auth_flag
, &info2
);
1169 NT_STATUS_NOT_OK_RETURN(status
);
1171 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_2
, info2
,
1172 (struct USER_INFO_2
**)buffer
, num_entries
);
1176 status
= info21_to_USER_INFO_3(mem_ctx
, info21
, auth_flag
, &info3
);
1177 NT_STATUS_NOT_OK_RETURN(status
);
1179 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_3
, info3
,
1180 (struct USER_INFO_3
**)buffer
, num_entries
);
1184 status
= info21_to_USER_INFO_4(mem_ctx
, info21
, auth_flag
, domain_sid
, &info4
);
1185 NT_STATUS_NOT_OK_RETURN(status
);
1187 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_4
, info4
,
1188 (struct USER_INFO_4
**)buffer
, num_entries
);
1192 status
= info21_to_USER_INFO_10(mem_ctx
, info21
, &info10
);
1193 NT_STATUS_NOT_OK_RETURN(status
);
1195 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_10
, info10
,
1196 (struct USER_INFO_10
**)buffer
, num_entries
);
1200 status
= info21_to_USER_INFO_11(mem_ctx
, info21
, auth_flag
, &info11
);
1201 NT_STATUS_NOT_OK_RETURN(status
);
1203 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_11
, info11
,
1204 (struct USER_INFO_11
**)buffer
, num_entries
);
1208 status
= info21_to_USER_INFO_20(mem_ctx
, info21
, &info20
);
1209 NT_STATUS_NOT_OK_RETURN(status
);
1211 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_20
, info20
,
1212 (struct USER_INFO_20
**)buffer
, num_entries
);
1216 status
= info21_to_USER_INFO_23(mem_ctx
, info21
, domain_sid
, &info23
);
1217 NT_STATUS_NOT_OK_RETURN(status
);
1219 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_23
, info23
,
1220 (struct USER_INFO_23
**)buffer
, num_entries
);
1223 return NT_STATUS_INVALID_LEVEL
;
1230 /****************************************************************
1231 ****************************************************************/
1233 WERROR
NetUserEnum_r(struct libnetapi_ctx
*ctx
,
1234 struct NetUserEnum
*r
)
1236 struct rpc_pipe_client
*pipe_cli
= NULL
;
1237 struct policy_handle connect_handle
;
1238 struct dom_sid2
*domain_sid
= NULL
;
1239 struct policy_handle domain_handle
, builtin_handle
;
1240 struct samr_SamArray
*sam
= NULL
;
1241 uint32_t filter
= ACB_NORMAL
;
1243 uint32_t entries_read
= 0;
1246 NTSTATUS result
= NT_STATUS_OK
;
1248 struct dcerpc_binding_handle
*b
= NULL
;
1250 ZERO_STRUCT(connect_handle
);
1251 ZERO_STRUCT(domain_handle
);
1252 ZERO_STRUCT(builtin_handle
);
1254 if (!r
->out
.buffer
) {
1255 return WERR_INVALID_PARAMETER
;
1258 *r
->out
.buffer
= NULL
;
1259 *r
->out
.entries_read
= 0;
1261 switch (r
->in
.level
) {
1273 return WERR_INVALID_LEVEL
;
1276 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1279 if (!W_ERROR_IS_OK(werr
)) {
1283 b
= pipe_cli
->binding_handle
;
1285 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1286 SAMR_ACCESS_ENUM_DOMAINS
|
1287 SAMR_ACCESS_LOOKUP_DOMAIN
,
1288 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1289 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1292 if (!W_ERROR_IS_OK(werr
)) {
1296 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1297 SAMR_ACCESS_ENUM_DOMAINS
|
1298 SAMR_ACCESS_LOOKUP_DOMAIN
,
1299 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1300 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1301 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1305 if (!W_ERROR_IS_OK(werr
)) {
1309 switch (r
->in
.filter
) {
1310 case FILTER_NORMAL_ACCOUNT
:
1311 filter
= ACB_NORMAL
;
1313 case FILTER_TEMP_DUPLICATE_ACCOUNT
:
1314 filter
= ACB_TEMPDUP
;
1316 case FILTER_INTERDOMAIN_TRUST_ACCOUNT
:
1317 filter
= ACB_DOMTRUST
;
1319 case FILTER_WORKSTATION_TRUST_ACCOUNT
:
1320 filter
= ACB_WSTRUST
;
1322 case FILTER_SERVER_TRUST_ACCOUNT
:
1323 filter
= ACB_SVRTRUST
;
1329 status
= dcerpc_samr_EnumDomainUsers(b
,
1332 r
->in
.resume_handle
,
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 werr
= ntstatus_to_werror(status
);
1342 werr
= ntstatus_to_werror(result
);
1343 if (NT_STATUS_IS_ERR(result
)) {
1347 for (i
=0; i
< sam
->count
; i
++) {
1349 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1353 sam
->entries
[i
].name
.string
,
1354 sam
->entries
[i
].idx
,
1357 r
->out
.entries_read
);
1358 if (!NT_STATUS_IS_OK(status
)) {
1359 werr
= ntstatus_to_werror(status
);
1366 if (NT_STATUS_IS_OK(result
) ||
1367 NT_STATUS_IS_ERR(result
)) {
1369 if (ctx
->disable_policy_handle_cache
) {
1370 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1371 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1372 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1379 /****************************************************************
1380 ****************************************************************/
1382 WERROR
NetUserEnum_l(struct libnetapi_ctx
*ctx
,
1383 struct NetUserEnum
*r
)
1385 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserEnum
);
1388 /****************************************************************
1389 ****************************************************************/
1391 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX
*mem_ctx
,
1392 struct samr_DispInfoGeneral
*info
,
1393 uint32_t *entries_read
,
1396 struct NET_DISPLAY_USER
*user
= NULL
;
1399 user
= talloc_zero_array(mem_ctx
,
1400 struct NET_DISPLAY_USER
,
1402 W_ERROR_HAVE_NO_MEMORY(user
);
1404 for (i
= 0; i
< info
->count
; i
++) {
1405 user
[i
].usri1_name
= talloc_strdup(mem_ctx
,
1406 info
->entries
[i
].account_name
.string
);
1407 user
[i
].usri1_comment
= talloc_strdup(mem_ctx
,
1408 info
->entries
[i
].description
.string
);
1409 user
[i
].usri1_flags
=
1410 info
->entries
[i
].acct_flags
;
1411 user
[i
].usri1_full_name
= talloc_strdup(mem_ctx
,
1412 info
->entries
[i
].full_name
.string
);
1413 user
[i
].usri1_user_id
=
1414 info
->entries
[i
].rid
;
1415 user
[i
].usri1_next_index
=
1416 info
->entries
[i
].idx
;
1418 if (!user
[i
].usri1_name
) {
1419 return WERR_NOT_ENOUGH_MEMORY
;
1423 *buffer
= talloc_memdup(mem_ctx
, user
,
1424 sizeof(struct NET_DISPLAY_USER
) * info
->count
);
1425 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1427 *entries_read
= info
->count
;
1432 /****************************************************************
1433 ****************************************************************/
1435 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX
*mem_ctx
,
1436 struct samr_DispInfoFull
*info
,
1437 uint32_t *entries_read
,
1440 struct NET_DISPLAY_MACHINE
*machine
= NULL
;
1443 machine
= talloc_zero_array(mem_ctx
,
1444 struct NET_DISPLAY_MACHINE
,
1446 W_ERROR_HAVE_NO_MEMORY(machine
);
1448 for (i
= 0; i
< info
->count
; i
++) {
1449 machine
[i
].usri2_name
= talloc_strdup(mem_ctx
,
1450 info
->entries
[i
].account_name
.string
);
1451 machine
[i
].usri2_comment
= talloc_strdup(mem_ctx
,
1452 info
->entries
[i
].description
.string
);
1453 machine
[i
].usri2_flags
=
1454 info
->entries
[i
].acct_flags
;
1455 machine
[i
].usri2_user_id
=
1456 info
->entries
[i
].rid
;
1457 machine
[i
].usri2_next_index
=
1458 info
->entries
[i
].idx
;
1460 if (!machine
[i
].usri2_name
) {
1461 return WERR_NOT_ENOUGH_MEMORY
;
1465 *buffer
= talloc_memdup(mem_ctx
, machine
,
1466 sizeof(struct NET_DISPLAY_MACHINE
) * info
->count
);
1467 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1469 *entries_read
= info
->count
;
1474 /****************************************************************
1475 ****************************************************************/
1477 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX
*mem_ctx
,
1478 struct samr_DispInfoFullGroups
*info
,
1479 uint32_t *entries_read
,
1482 struct NET_DISPLAY_GROUP
*group
= NULL
;
1485 group
= talloc_zero_array(mem_ctx
,
1486 struct NET_DISPLAY_GROUP
,
1488 W_ERROR_HAVE_NO_MEMORY(group
);
1490 for (i
= 0; i
< info
->count
; i
++) {
1491 group
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1492 info
->entries
[i
].account_name
.string
);
1493 group
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1494 info
->entries
[i
].description
.string
);
1495 group
[i
].grpi3_group_id
=
1496 info
->entries
[i
].rid
;
1497 group
[i
].grpi3_attributes
=
1498 info
->entries
[i
].acct_flags
;
1499 group
[i
].grpi3_next_index
=
1500 info
->entries
[i
].idx
;
1502 if (!group
[i
].grpi3_name
) {
1503 return WERR_NOT_ENOUGH_MEMORY
;
1507 *buffer
= talloc_memdup(mem_ctx
, group
,
1508 sizeof(struct NET_DISPLAY_GROUP
) * info
->count
);
1509 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1511 *entries_read
= info
->count
;
1517 /****************************************************************
1518 ****************************************************************/
1520 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX
*mem_ctx
,
1521 union samr_DispInfo
*info
,
1523 uint32_t *entries_read
,
1528 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx
,
1533 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx
,
1538 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx
,
1546 return WERR_INVALID_LEVEL
;
1549 /****************************************************************
1550 ****************************************************************/
1552 WERROR
NetQueryDisplayInformation_r(struct libnetapi_ctx
*ctx
,
1553 struct NetQueryDisplayInformation
*r
)
1555 struct rpc_pipe_client
*pipe_cli
= NULL
;
1556 struct policy_handle connect_handle
;
1557 struct dom_sid2
*domain_sid
= NULL
;
1558 struct policy_handle domain_handle
;
1559 union samr_DispInfo info
;
1560 struct dcerpc_binding_handle
*b
= NULL
;
1562 uint32_t total_size
= 0;
1563 uint32_t returned_size
= 0;
1566 NTSTATUS result
= NT_STATUS_OK
;
1570 *r
->out
.entries_read
= 0;
1572 ZERO_STRUCT(connect_handle
);
1573 ZERO_STRUCT(domain_handle
);
1575 switch (r
->in
.level
) {
1581 return WERR_INVALID_LEVEL
;
1584 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1587 if (!W_ERROR_IS_OK(werr
)) {
1591 b
= pipe_cli
->binding_handle
;
1593 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1594 SAMR_ACCESS_ENUM_DOMAINS
|
1595 SAMR_ACCESS_LOOKUP_DOMAIN
,
1596 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1597 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1598 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1602 if (!W_ERROR_IS_OK(werr
)) {
1606 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1611 r
->in
.entries_requested
,
1617 if (!NT_STATUS_IS_OK(status
)) {
1618 werr
= ntstatus_to_werror(status
);
1621 werr
= ntstatus_to_werror(result
);
1622 if (NT_STATUS_IS_ERR(result
)) {
1626 werr_tmp
= convert_samr_dispinfo_to_NET_DISPLAY(ctx
, &info
,
1628 r
->out
.entries_read
,
1630 if (!W_ERROR_IS_OK(werr_tmp
)) {
1635 if (NT_STATUS_IS_OK(result
) ||
1636 NT_STATUS_IS_ERR(result
)) {
1638 if (ctx
->disable_policy_handle_cache
) {
1639 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1640 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1648 /****************************************************************
1649 ****************************************************************/
1652 WERROR
NetQueryDisplayInformation_l(struct libnetapi_ctx
*ctx
,
1653 struct NetQueryDisplayInformation
*r
)
1655 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetQueryDisplayInformation
);
1658 /****************************************************************
1659 ****************************************************************/
1661 WERROR
NetUserChangePassword_r(struct libnetapi_ctx
*ctx
,
1662 struct NetUserChangePassword
*r
)
1664 return WERR_NOT_SUPPORTED
;
1667 /****************************************************************
1668 ****************************************************************/
1670 WERROR
NetUserChangePassword_l(struct libnetapi_ctx
*ctx
,
1671 struct NetUserChangePassword
*r
)
1673 return WERR_NOT_SUPPORTED
;
1676 /****************************************************************
1677 ****************************************************************/
1679 WERROR
NetUserGetInfo_r(struct libnetapi_ctx
*ctx
,
1680 struct NetUserGetInfo
*r
)
1682 struct rpc_pipe_client
*pipe_cli
= NULL
;
1683 NTSTATUS status
, result
;
1686 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1687 struct lsa_String lsa_account_name
;
1688 struct dom_sid2
*domain_sid
= NULL
;
1689 struct samr_Ids user_rids
, name_types
;
1690 uint32_t num_entries
= 0;
1691 struct dcerpc_binding_handle
*b
= NULL
;
1693 ZERO_STRUCT(connect_handle
);
1694 ZERO_STRUCT(domain_handle
);
1695 ZERO_STRUCT(builtin_handle
);
1696 ZERO_STRUCT(user_handle
);
1698 if (!r
->out
.buffer
) {
1699 return WERR_INVALID_PARAMETER
;
1702 switch (r
->in
.level
) {
1714 werr
= WERR_INVALID_LEVEL
;
1718 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1721 if (!W_ERROR_IS_OK(werr
)) {
1725 b
= pipe_cli
->binding_handle
;
1727 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1728 SAMR_ACCESS_ENUM_DOMAINS
|
1729 SAMR_ACCESS_LOOKUP_DOMAIN
,
1730 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1734 if (!W_ERROR_IS_OK(werr
)) {
1738 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1739 SAMR_ACCESS_ENUM_DOMAINS
|
1740 SAMR_ACCESS_LOOKUP_DOMAIN
,
1741 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1742 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1745 if (!W_ERROR_IS_OK(werr
)) {
1749 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1751 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1758 if (any_nt_status_not_ok(status
, result
, &status
)) {
1759 werr
= ntstatus_to_werror(status
);
1762 if (user_rids
.count
!= 1) {
1763 werr
= WERR_BAD_NET_RESP
;
1766 if (name_types
.count
!= 1) {
1767 werr
= WERR_BAD_NET_RESP
;
1771 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1780 if (!NT_STATUS_IS_OK(status
)) {
1781 werr
= ntstatus_to_werror(status
);
1786 if (is_valid_policy_hnd(&user_handle
) && b
) {
1787 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1790 if (ctx
->disable_policy_handle_cache
) {
1791 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1792 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1798 /****************************************************************
1799 ****************************************************************/
1801 WERROR
NetUserGetInfo_l(struct libnetapi_ctx
*ctx
,
1802 struct NetUserGetInfo
*r
)
1804 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetInfo
);
1807 /****************************************************************
1808 ****************************************************************/
1810 WERROR
NetUserSetInfo_r(struct libnetapi_ctx
*ctx
,
1811 struct NetUserSetInfo
*r
)
1813 struct rpc_pipe_client
*pipe_cli
= NULL
;
1814 NTSTATUS status
, result
;
1817 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1818 struct lsa_String lsa_account_name
;
1819 struct dom_sid2
*domain_sid
= NULL
;
1820 struct samr_Ids user_rids
, name_types
;
1821 uint32_t user_mask
= 0;
1823 struct USER_INFO_X uX
;
1824 struct dcerpc_binding_handle
*b
= NULL
;
1825 DATA_BLOB session_key
;
1827 ZERO_STRUCT(connect_handle
);
1828 ZERO_STRUCT(domain_handle
);
1829 ZERO_STRUCT(builtin_handle
);
1830 ZERO_STRUCT(user_handle
);
1832 if (!r
->in
.buffer
) {
1833 return WERR_INVALID_PARAMETER
;
1836 switch (r
->in
.level
) {
1838 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1841 user_mask
= SAMR_USER_ACCESS_SET_PASSWORD
;
1850 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1854 user_mask
= SAMR_USER_ACCESS_SET_LOC_COM
;
1857 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1858 SAMR_USER_ACCESS_GET_GROUPS
;
1861 user_mask
= SEC_STD_READ_CONTROL
|
1863 SAMR_USER_ACCESS_GET_GROUPS
|
1864 SAMR_USER_ACCESS_SET_PASSWORD
|
1865 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1866 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
1867 SAMR_USER_ACCESS_SET_LOC_COM
;
1879 werr
= WERR_NOT_SUPPORTED
;
1882 werr
= WERR_INVALID_LEVEL
;
1886 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1889 if (!W_ERROR_IS_OK(werr
)) {
1893 b
= pipe_cli
->binding_handle
;
1895 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1896 SAMR_ACCESS_ENUM_DOMAINS
|
1897 SAMR_ACCESS_LOOKUP_DOMAIN
,
1898 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
1899 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1903 if (!W_ERROR_IS_OK(werr
)) {
1907 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1908 SAMR_ACCESS_ENUM_DOMAINS
|
1909 SAMR_ACCESS_LOOKUP_DOMAIN
,
1910 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1911 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1914 if (!W_ERROR_IS_OK(werr
)) {
1918 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1920 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1927 if (any_nt_status_not_ok(status
, result
, &status
)) {
1928 werr
= ntstatus_to_werror(status
);
1931 if (user_rids
.count
!= 1) {
1932 werr
= WERR_BAD_NET_RESP
;
1935 if (name_types
.count
!= 1) {
1936 werr
= WERR_BAD_NET_RESP
;
1940 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
1946 if (any_nt_status_not_ok(status
, result
, &status
)) {
1947 werr
= ntstatus_to_werror(status
);
1951 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
1952 if (!NT_STATUS_IS_OK(status
)) {
1953 werr
= ntstatus_to_werror(status
);
1957 status
= dcerpc_binding_handle_transport_session_key(
1958 b
, talloc_tos(), &session_key
);
1959 if (!NT_STATUS_IS_OK(status
)) {
1960 werr
= ntstatus_to_werror(status
);
1964 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
1968 if (!NT_STATUS_IS_OK(status
)) {
1969 werr
= ntstatus_to_werror(status
);
1976 if (is_valid_policy_hnd(&user_handle
) && b
) {
1977 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1980 if (ctx
->disable_policy_handle_cache
) {
1981 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1982 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1983 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1989 /****************************************************************
1990 ****************************************************************/
1992 WERROR
NetUserSetInfo_l(struct libnetapi_ctx
*ctx
,
1993 struct NetUserSetInfo
*r
)
1995 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetInfo
);
1998 /****************************************************************
1999 ****************************************************************/
2001 static NTSTATUS
query_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2002 struct rpc_pipe_client
*pipe_cli
,
2003 struct policy_handle
*domain_handle
,
2004 struct samr_DomInfo1
*info1
,
2005 struct samr_DomInfo3
*info3
,
2006 struct samr_DomInfo5
*info5
,
2007 struct samr_DomInfo6
*info6
,
2008 struct samr_DomInfo7
*info7
,
2009 struct samr_DomInfo12
*info12
)
2011 NTSTATUS status
, result
;
2012 union samr_DomainInfo
*dom_info
= NULL
;
2013 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2016 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2021 NT_STATUS_NOT_OK_RETURN(status
);
2022 NT_STATUS_NOT_OK_RETURN(result
);
2024 *info1
= dom_info
->info1
;
2028 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2033 NT_STATUS_NOT_OK_RETURN(status
);
2034 NT_STATUS_NOT_OK_RETURN(result
);
2036 *info3
= dom_info
->info3
;
2040 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2045 NT_STATUS_NOT_OK_RETURN(status
);
2046 NT_STATUS_NOT_OK_RETURN(result
);
2048 *info5
= dom_info
->info5
;
2052 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2057 NT_STATUS_NOT_OK_RETURN(status
);
2058 NT_STATUS_NOT_OK_RETURN(result
);
2060 *info6
= dom_info
->info6
;
2064 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2069 NT_STATUS_NOT_OK_RETURN(status
);
2070 NT_STATUS_NOT_OK_RETURN(result
);
2072 *info7
= dom_info
->info7
;
2076 status
= dcerpc_samr_QueryDomainInfo2(b
, mem_ctx
,
2081 NT_STATUS_NOT_OK_RETURN(status
);
2082 NT_STATUS_NOT_OK_RETURN(result
);
2084 *info12
= dom_info
->info12
;
2087 return NT_STATUS_OK
;
2090 /****************************************************************
2091 ****************************************************************/
2093 static NTSTATUS
query_USER_MODALS_INFO_0(TALLOC_CTX
*mem_ctx
,
2094 struct rpc_pipe_client
*pipe_cli
,
2095 struct policy_handle
*domain_handle
,
2096 struct USER_MODALS_INFO_0
*info0
)
2099 struct samr_DomInfo1 dom_info1
;
2100 struct samr_DomInfo3 dom_info3
;
2102 ZERO_STRUCTP(info0
);
2104 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2113 NT_STATUS_NOT_OK_RETURN(status
);
2115 info0
->usrmod0_min_passwd_len
=
2116 dom_info1
.min_password_length
;
2117 info0
->usrmod0_max_passwd_age
=
2118 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.max_password_age
);
2119 info0
->usrmod0_min_passwd_age
=
2120 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.min_password_age
);
2121 info0
->usrmod0_password_hist_len
=
2122 dom_info1
.password_history_length
;
2124 info0
->usrmod0_force_logoff
=
2125 nt_time_to_unix_abs(&dom_info3
.force_logoff_time
);
2127 return NT_STATUS_OK
;
2130 /****************************************************************
2131 ****************************************************************/
2133 static NTSTATUS
query_USER_MODALS_INFO_1(TALLOC_CTX
*mem_ctx
,
2134 struct rpc_pipe_client
*pipe_cli
,
2135 struct policy_handle
*domain_handle
,
2136 struct USER_MODALS_INFO_1
*info1
)
2139 struct samr_DomInfo6 dom_info6
;
2140 struct samr_DomInfo7 dom_info7
;
2142 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2151 NT_STATUS_NOT_OK_RETURN(status
);
2153 info1
->usrmod1_primary
=
2154 talloc_strdup(mem_ctx
, dom_info6
.primary
.string
);
2156 info1
->usrmod1_role
= dom_info7
.role
;
2158 return NT_STATUS_OK
;
2161 /****************************************************************
2162 ****************************************************************/
2164 static NTSTATUS
query_USER_MODALS_INFO_2(TALLOC_CTX
*mem_ctx
,
2165 struct rpc_pipe_client
*pipe_cli
,
2166 struct policy_handle
*domain_handle
,
2167 struct dom_sid
*domain_sid
,
2168 struct USER_MODALS_INFO_2
*info2
)
2171 struct samr_DomInfo5 dom_info5
;
2173 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2182 NT_STATUS_NOT_OK_RETURN(status
);
2184 info2
->usrmod2_domain_name
=
2185 talloc_strdup(mem_ctx
, dom_info5
.domain_name
.string
);
2186 info2
->usrmod2_domain_id
=
2187 (struct domsid
*)dom_sid_dup(mem_ctx
, domain_sid
);
2189 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_name
);
2190 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_id
);
2192 return NT_STATUS_OK
;
2195 /****************************************************************
2196 ****************************************************************/
2198 static NTSTATUS
query_USER_MODALS_INFO_3(TALLOC_CTX
*mem_ctx
,
2199 struct rpc_pipe_client
*pipe_cli
,
2200 struct policy_handle
*domain_handle
,
2201 struct USER_MODALS_INFO_3
*info3
)
2204 struct samr_DomInfo12 dom_info12
;
2206 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2215 NT_STATUS_NOT_OK_RETURN(status
);
2217 info3
->usrmod3_lockout_duration
=
2218 nt_time_to_unix_abs(&dom_info12
.lockout_duration
);
2219 info3
->usrmod3_lockout_observation_window
=
2220 nt_time_to_unix_abs(&dom_info12
.lockout_window
);
2221 info3
->usrmod3_lockout_threshold
=
2222 dom_info12
.lockout_threshold
;
2224 return NT_STATUS_OK
;
2227 /****************************************************************
2228 ****************************************************************/
2230 static NTSTATUS
query_USER_MODALS_INFO_to_buffer(TALLOC_CTX
*mem_ctx
,
2231 struct rpc_pipe_client
*pipe_cli
,
2233 struct policy_handle
*domain_handle
,
2234 struct dom_sid
*domain_sid
,
2239 struct USER_MODALS_INFO_0 info0
;
2240 struct USER_MODALS_INFO_1 info1
;
2241 struct USER_MODALS_INFO_2 info2
;
2242 struct USER_MODALS_INFO_3 info3
;
2245 return ERROR_INSUFFICIENT_BUFFER
;
2250 status
= query_USER_MODALS_INFO_0(mem_ctx
,
2254 NT_STATUS_NOT_OK_RETURN(status
);
2256 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
,
2261 status
= query_USER_MODALS_INFO_1(mem_ctx
,
2265 NT_STATUS_NOT_OK_RETURN(status
);
2267 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
,
2271 status
= query_USER_MODALS_INFO_2(mem_ctx
,
2276 NT_STATUS_NOT_OK_RETURN(status
);
2278 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
,
2282 status
= query_USER_MODALS_INFO_3(mem_ctx
,
2286 NT_STATUS_NOT_OK_RETURN(status
);
2288 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
,
2295 NT_STATUS_HAVE_NO_MEMORY(*buffer
);
2297 return NT_STATUS_OK
;
2300 /****************************************************************
2301 ****************************************************************/
2303 WERROR
NetUserModalsGet_r(struct libnetapi_ctx
*ctx
,
2304 struct NetUserModalsGet
*r
)
2306 struct rpc_pipe_client
*pipe_cli
= NULL
;
2310 struct policy_handle connect_handle
, domain_handle
;
2311 struct dom_sid2
*domain_sid
= NULL
;
2312 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2314 ZERO_STRUCT(connect_handle
);
2315 ZERO_STRUCT(domain_handle
);
2317 if (!r
->out
.buffer
) {
2318 return WERR_INVALID_PARAMETER
;
2321 switch (r
->in
.level
) {
2323 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2324 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2328 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2331 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
2334 werr
= WERR_INVALID_LEVEL
;
2338 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2341 if (!W_ERROR_IS_OK(werr
)) {
2345 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2346 SAMR_ACCESS_ENUM_DOMAINS
|
2347 SAMR_ACCESS_LOOKUP_DOMAIN
,
2352 if (!W_ERROR_IS_OK(werr
)) {
2359 /* 3: 12 (DomainInfo2) */
2361 status
= query_USER_MODALS_INFO_to_buffer(ctx
,
2367 if (!NT_STATUS_IS_OK(status
)) {
2368 werr
= ntstatus_to_werror(status
);
2373 if (ctx
->disable_policy_handle_cache
) {
2374 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2375 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2381 /****************************************************************
2382 ****************************************************************/
2384 WERROR
NetUserModalsGet_l(struct libnetapi_ctx
*ctx
,
2385 struct NetUserModalsGet
*r
)
2387 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsGet
);
2390 /****************************************************************
2391 ****************************************************************/
2393 static NTSTATUS
set_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2394 struct rpc_pipe_client
*pipe_cli
,
2395 struct policy_handle
*domain_handle
,
2396 struct samr_DomInfo1
*info1
,
2397 struct samr_DomInfo3
*info3
,
2398 struct samr_DomInfo12
*info12
)
2400 NTSTATUS status
, result
;
2401 union samr_DomainInfo dom_info
;
2402 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2406 ZERO_STRUCT(dom_info
);
2408 dom_info
.info1
= *info1
;
2410 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2415 NT_STATUS_NOT_OK_RETURN(status
);
2416 NT_STATUS_NOT_OK_RETURN(result
);
2421 ZERO_STRUCT(dom_info
);
2423 dom_info
.info3
= *info3
;
2425 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2431 NT_STATUS_NOT_OK_RETURN(status
);
2432 NT_STATUS_NOT_OK_RETURN(result
);
2437 ZERO_STRUCT(dom_info
);
2439 dom_info
.info12
= *info12
;
2441 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2447 NT_STATUS_NOT_OK_RETURN(status
);
2448 NT_STATUS_NOT_OK_RETURN(result
);
2451 return NT_STATUS_OK
;
2454 /****************************************************************
2455 ****************************************************************/
2457 static NTSTATUS
set_USER_MODALS_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
2458 struct rpc_pipe_client
*pipe_cli
,
2459 struct policy_handle
*domain_handle
,
2460 struct USER_MODALS_INFO_0
*info0
)
2463 struct samr_DomInfo1 dom_info_1
;
2464 struct samr_DomInfo3 dom_info_3
;
2466 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2475 NT_STATUS_NOT_OK_RETURN(status
);
2477 dom_info_1
.min_password_length
=
2478 info0
->usrmod0_min_passwd_len
;
2479 dom_info_1
.password_history_length
=
2480 info0
->usrmod0_password_hist_len
;
2482 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2483 info0
->usrmod0_max_passwd_age
);
2484 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2485 info0
->usrmod0_min_passwd_age
);
2487 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2488 info0
->usrmod0_force_logoff
);
2490 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2498 /****************************************************************
2499 ****************************************************************/
2501 static NTSTATUS
set_USER_MODALS_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
2502 struct rpc_pipe_client
*pipe_cli
,
2503 struct policy_handle
*domain_handle
,
2504 struct USER_MODALS_INFO_3
*info3
)
2507 struct samr_DomInfo12 dom_info_12
;
2509 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2518 NT_STATUS_NOT_OK_RETURN(status
);
2520 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_duration
,
2521 info3
->usrmod3_lockout_duration
);
2522 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_window
,
2523 info3
->usrmod3_lockout_observation_window
);
2524 dom_info_12
.lockout_threshold
= info3
->usrmod3_lockout_threshold
;
2526 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2534 /****************************************************************
2535 ****************************************************************/
2537 static NTSTATUS
set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX
*mem_ctx
,
2538 struct rpc_pipe_client
*pipe_cli
,
2539 struct policy_handle
*domain_handle
,
2540 struct USER_MODALS_INFO_1001
*info1001
)
2543 struct samr_DomInfo1 dom_info_1
;
2545 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2554 NT_STATUS_NOT_OK_RETURN(status
);
2556 dom_info_1
.min_password_length
=
2557 info1001
->usrmod1001_min_passwd_len
;
2559 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2567 /****************************************************************
2568 ****************************************************************/
2570 static NTSTATUS
set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX
*mem_ctx
,
2571 struct rpc_pipe_client
*pipe_cli
,
2572 struct policy_handle
*domain_handle
,
2573 struct USER_MODALS_INFO_1002
*info1002
)
2576 struct samr_DomInfo1 dom_info_1
;
2578 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2587 NT_STATUS_NOT_OK_RETURN(status
);
2589 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2590 info1002
->usrmod1002_max_passwd_age
);
2592 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2600 /****************************************************************
2601 ****************************************************************/
2603 static NTSTATUS
set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX
*mem_ctx
,
2604 struct rpc_pipe_client
*pipe_cli
,
2605 struct policy_handle
*domain_handle
,
2606 struct USER_MODALS_INFO_1003
*info1003
)
2609 struct samr_DomInfo1 dom_info_1
;
2611 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2620 NT_STATUS_NOT_OK_RETURN(status
);
2622 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2623 info1003
->usrmod1003_min_passwd_age
);
2625 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2633 /****************************************************************
2634 ****************************************************************/
2636 static NTSTATUS
set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX
*mem_ctx
,
2637 struct rpc_pipe_client
*pipe_cli
,
2638 struct policy_handle
*domain_handle
,
2639 struct USER_MODALS_INFO_1004
*info1004
)
2642 struct samr_DomInfo3 dom_info_3
;
2644 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2653 NT_STATUS_NOT_OK_RETURN(status
);
2655 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2656 info1004
->usrmod1004_force_logoff
);
2658 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2666 /****************************************************************
2667 ****************************************************************/
2669 static NTSTATUS
set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX
*mem_ctx
,
2670 struct rpc_pipe_client
*pipe_cli
,
2671 struct policy_handle
*domain_handle
,
2672 struct USER_MODALS_INFO_1005
*info1005
)
2675 struct samr_DomInfo1 dom_info_1
;
2677 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2686 NT_STATUS_NOT_OK_RETURN(status
);
2688 dom_info_1
.password_history_length
=
2689 info1005
->usrmod1005_password_hist_len
;
2691 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2699 /****************************************************************
2700 ****************************************************************/
2702 static NTSTATUS
set_USER_MODALS_INFO_buffer(TALLOC_CTX
*mem_ctx
,
2703 struct rpc_pipe_client
*pipe_cli
,
2705 struct policy_handle
*domain_handle
,
2706 struct dom_sid
*domain_sid
,
2709 struct USER_MODALS_INFO_0
*info0
;
2710 struct USER_MODALS_INFO_3
*info3
;
2711 struct USER_MODALS_INFO_1001
*info1001
;
2712 struct USER_MODALS_INFO_1002
*info1002
;
2713 struct USER_MODALS_INFO_1003
*info1003
;
2714 struct USER_MODALS_INFO_1004
*info1004
;
2715 struct USER_MODALS_INFO_1005
*info1005
;
2718 return ERROR_INSUFFICIENT_BUFFER
;
2723 info0
= (struct USER_MODALS_INFO_0
*)buffer
;
2724 return set_USER_MODALS_INFO_0_buffer(mem_ctx
,
2729 info3
= (struct USER_MODALS_INFO_3
*)buffer
;
2730 return set_USER_MODALS_INFO_3_buffer(mem_ctx
,
2735 info1001
= (struct USER_MODALS_INFO_1001
*)buffer
;
2736 return set_USER_MODALS_INFO_1001_buffer(mem_ctx
,
2741 info1002
= (struct USER_MODALS_INFO_1002
*)buffer
;
2742 return set_USER_MODALS_INFO_1002_buffer(mem_ctx
,
2747 info1003
= (struct USER_MODALS_INFO_1003
*)buffer
;
2748 return set_USER_MODALS_INFO_1003_buffer(mem_ctx
,
2753 info1004
= (struct USER_MODALS_INFO_1004
*)buffer
;
2754 return set_USER_MODALS_INFO_1004_buffer(mem_ctx
,
2759 info1005
= (struct USER_MODALS_INFO_1005
*)buffer
;
2760 return set_USER_MODALS_INFO_1005_buffer(mem_ctx
,
2769 return NT_STATUS_OK
;
2772 /****************************************************************
2773 ****************************************************************/
2775 WERROR
NetUserModalsSet_r(struct libnetapi_ctx
*ctx
,
2776 struct NetUserModalsSet
*r
)
2778 struct rpc_pipe_client
*pipe_cli
= NULL
;
2782 struct policy_handle connect_handle
, domain_handle
;
2783 struct dom_sid2
*domain_sid
= NULL
;
2784 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2786 ZERO_STRUCT(connect_handle
);
2787 ZERO_STRUCT(domain_handle
);
2789 if (!r
->in
.buffer
) {
2790 return WERR_INVALID_PARAMETER
;
2793 switch (r
->in
.level
) {
2795 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2796 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2797 SAMR_DOMAIN_ACCESS_SET_INFO_1
|
2798 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2805 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2806 SAMR_DOMAIN_ACCESS_SET_INFO_1
;
2809 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2810 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2816 werr
= WERR_NOT_SUPPORTED
;
2819 werr
= WERR_INVALID_LEVEL
;
2823 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2826 if (!W_ERROR_IS_OK(werr
)) {
2830 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2831 SAMR_ACCESS_ENUM_DOMAINS
|
2832 SAMR_ACCESS_LOOKUP_DOMAIN
,
2837 if (!W_ERROR_IS_OK(werr
)) {
2841 status
= set_USER_MODALS_INFO_buffer(ctx
,
2847 if (!NT_STATUS_IS_OK(status
)) {
2848 werr
= ntstatus_to_werror(status
);
2853 if (ctx
->disable_policy_handle_cache
) {
2854 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2855 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2861 /****************************************************************
2862 ****************************************************************/
2864 WERROR
NetUserModalsSet_l(struct libnetapi_ctx
*ctx
,
2865 struct NetUserModalsSet
*r
)
2867 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsSet
);
2870 /****************************************************************
2871 ****************************************************************/
2873 NTSTATUS
add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
2875 const char *group_name
,
2876 uint32_t attributes
,
2878 uint32_t *num_entries
)
2880 struct GROUP_USERS_INFO_0 u0
;
2881 struct GROUP_USERS_INFO_1 u1
;
2886 u0
.grui0_name
= talloc_strdup(mem_ctx
, group_name
);
2887 NT_STATUS_HAVE_NO_MEMORY(u0
.grui0_name
);
2889 u0
.grui0_name
= NULL
;
2892 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_0
, u0
,
2893 (struct GROUP_USERS_INFO_0
**)buffer
, num_entries
);
2897 u1
.grui1_name
= talloc_strdup(mem_ctx
, group_name
);
2898 NT_STATUS_HAVE_NO_MEMORY(u1
.grui1_name
);
2900 u1
.grui1_name
= NULL
;
2903 u1
.grui1_attributes
= attributes
;
2905 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_1
, u1
,
2906 (struct GROUP_USERS_INFO_1
**)buffer
, num_entries
);
2909 return NT_STATUS_INVALID_INFO_CLASS
;
2912 return NT_STATUS_OK
;
2915 /****************************************************************
2916 ****************************************************************/
2918 WERROR
NetUserGetGroups_r(struct libnetapi_ctx
*ctx
,
2919 struct NetUserGetGroups
*r
)
2921 struct rpc_pipe_client
*pipe_cli
= NULL
;
2922 struct policy_handle connect_handle
, domain_handle
, user_handle
;
2923 struct lsa_String lsa_account_name
;
2924 struct dom_sid2
*domain_sid
= NULL
;
2925 struct samr_Ids user_rids
, name_types
;
2926 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
2927 struct lsa_Strings names
;
2928 struct samr_Ids types
;
2929 uint32_t *rids
= NULL
;
2932 uint32_t entries_read
= 0;
2935 NTSTATUS result
= NT_STATUS_OK
;
2937 struct dcerpc_binding_handle
*b
= NULL
;
2939 ZERO_STRUCT(connect_handle
);
2940 ZERO_STRUCT(domain_handle
);
2942 if (!r
->out
.buffer
) {
2943 return WERR_INVALID_PARAMETER
;
2946 *r
->out
.buffer
= NULL
;
2947 *r
->out
.entries_read
= 0;
2948 *r
->out
.total_entries
= 0;
2950 switch (r
->in
.level
) {
2955 return WERR_INVALID_LEVEL
;
2958 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2961 if (!W_ERROR_IS_OK(werr
)) {
2965 b
= pipe_cli
->binding_handle
;
2967 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2968 SAMR_ACCESS_ENUM_DOMAINS
|
2969 SAMR_ACCESS_LOOKUP_DOMAIN
,
2970 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
2974 if (!W_ERROR_IS_OK(werr
)) {
2978 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
2980 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
2987 if (any_nt_status_not_ok(status
, result
, &status
)) {
2988 werr
= ntstatus_to_werror(status
);
2991 if (user_rids
.count
!= 1) {
2992 werr
= WERR_BAD_NET_RESP
;
2995 if (name_types
.count
!= 1) {
2996 werr
= WERR_BAD_NET_RESP
;
3000 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3002 SAMR_USER_ACCESS_GET_GROUPS
,
3006 if (any_nt_status_not_ok(status
, result
, &status
)) {
3007 werr
= ntstatus_to_werror(status
);
3011 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3015 if (any_nt_status_not_ok(status
, result
, &status
)) {
3016 werr
= ntstatus_to_werror(status
);
3020 rids
= talloc_array(ctx
, uint32_t, rid_array
->count
);
3022 werr
= WERR_NOT_ENOUGH_MEMORY
;
3026 for (i
=0; i
< rid_array
->count
; i
++) {
3027 rids
[i
] = rid_array
->rids
[i
].rid
;
3030 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3037 if (!NT_STATUS_IS_OK(status
)) {
3038 werr
= ntstatus_to_werror(status
);
3041 if (!NT_STATUS_IS_OK(result
) &&
3042 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3043 werr
= ntstatus_to_werror(result
);
3046 if (names
.count
!= rid_array
->count
) {
3047 werr
= WERR_BAD_NET_RESP
;
3050 if (types
.count
!= rid_array
->count
) {
3051 werr
= WERR_BAD_NET_RESP
;
3055 for (i
=0; i
< names
.count
; i
++) {
3056 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
3058 names
.names
[i
].string
,
3059 rid_array
->rids
[i
].attributes
,
3062 if (!NT_STATUS_IS_OK(status
)) {
3063 werr
= ntstatus_to_werror(status
);
3068 *r
->out
.entries_read
= entries_read
;
3069 *r
->out
.total_entries
= entries_read
;
3072 if (ctx
->disable_policy_handle_cache
) {
3073 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3074 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3080 /****************************************************************
3081 ****************************************************************/
3083 WERROR
NetUserGetGroups_l(struct libnetapi_ctx
*ctx
,
3084 struct NetUserGetGroups
*r
)
3086 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetGroups
);
3089 /****************************************************************
3090 ****************************************************************/
3092 WERROR
NetUserSetGroups_r(struct libnetapi_ctx
*ctx
,
3093 struct NetUserSetGroups
*r
)
3095 struct rpc_pipe_client
*pipe_cli
= NULL
;
3096 struct policy_handle connect_handle
, domain_handle
, user_handle
, group_handle
;
3097 struct lsa_String lsa_account_name
;
3098 struct dom_sid2
*domain_sid
= NULL
;
3099 struct samr_Ids user_rids
, name_types
;
3100 struct samr_Ids group_rids
;
3101 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3102 struct lsa_String
*lsa_names
= NULL
;
3104 uint32_t *add_rids
= NULL
;
3105 uint32_t *del_rids
= NULL
;
3106 size_t num_add_rids
= 0;
3107 size_t num_del_rids
= 0;
3109 uint32_t *member_rids
= NULL
;
3111 struct GROUP_USERS_INFO_0
*i0
= NULL
;
3112 struct GROUP_USERS_INFO_1
*i1
= NULL
;
3117 NTSTATUS result
= NT_STATUS_OK
;
3119 struct dcerpc_binding_handle
*b
= NULL
;
3121 ZERO_STRUCT(connect_handle
);
3122 ZERO_STRUCT(domain_handle
);
3123 ZERO_STRUCT(group_handle
);
3125 if (!r
->in
.buffer
) {
3126 return WERR_INVALID_PARAMETER
;
3129 switch (r
->in
.level
) {
3134 return WERR_INVALID_LEVEL
;
3137 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3140 if (!W_ERROR_IS_OK(werr
)) {
3144 b
= pipe_cli
->binding_handle
;
3146 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3147 SAMR_ACCESS_ENUM_DOMAINS
|
3148 SAMR_ACCESS_LOOKUP_DOMAIN
,
3149 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3153 if (!W_ERROR_IS_OK(werr
)) {
3157 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3159 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3166 if (any_nt_status_not_ok(status
, result
, &status
)) {
3167 werr
= ntstatus_to_werror(status
);
3170 if (user_rids
.count
!= 1) {
3171 werr
= WERR_BAD_NET_RESP
;
3174 if (name_types
.count
!= 1) {
3175 werr
= WERR_BAD_NET_RESP
;
3179 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3181 SAMR_USER_ACCESS_GET_GROUPS
,
3185 if (any_nt_status_not_ok(status
, result
, &status
)) {
3186 werr
= ntstatus_to_werror(status
);
3190 switch (r
->in
.level
) {
3192 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
3195 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
3199 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
3201 werr
= WERR_NOT_ENOUGH_MEMORY
;
3205 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3207 switch (r
->in
.level
) {
3209 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
3213 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
3219 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3226 if (any_nt_status_not_ok(status
, result
, &status
)) {
3227 werr
= ntstatus_to_werror(status
);
3230 if (group_rids
.count
!= r
->in
.num_entries
) {
3231 werr
= WERR_BAD_NET_RESP
;
3234 if (name_types
.count
!= r
->in
.num_entries
) {
3235 werr
= WERR_BAD_NET_RESP
;
3239 member_rids
= group_rids
.ids
;
3241 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3245 if (any_nt_status_not_ok(status
, result
, &status
)) {
3246 werr
= ntstatus_to_werror(status
);
3252 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3253 bool already_member
= false;
3254 for (k
=0; k
< rid_array
->count
; k
++) {
3255 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3256 already_member
= true;
3260 if (!already_member
) {
3261 if (!add_rid_to_array_unique(ctx
,
3263 &add_rids
, &num_add_rids
)) {
3264 werr
= WERR_GEN_FAILURE
;
3272 for (k
=0; k
< rid_array
->count
; k
++) {
3273 bool keep_member
= false;
3274 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3275 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3281 if (!add_rid_to_array_unique(ctx
,
3282 rid_array
->rids
[k
].rid
,
3283 &del_rids
, &num_del_rids
)) {
3284 werr
= WERR_GEN_FAILURE
;
3292 for (i
=0; i
< num_add_rids
; i
++) {
3293 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3295 SAMR_GROUP_ACCESS_ADD_MEMBER
,
3299 if (any_nt_status_not_ok(status
, result
, &status
)) {
3300 werr
= ntstatus_to_werror(status
);
3304 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
3309 if (any_nt_status_not_ok(status
, result
, &status
)) {
3310 werr
= ntstatus_to_werror(status
);
3314 if (is_valid_policy_hnd(&group_handle
)) {
3315 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3321 for (i
=0; i
< num_del_rids
; i
++) {
3322 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3324 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
3328 if (any_nt_status_not_ok(status
, result
, &status
)) {
3329 werr
= ntstatus_to_werror(status
);
3333 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
3337 if (any_nt_status_not_ok(status
, result
, &status
)) {
3338 werr
= ntstatus_to_werror(status
);
3342 if (is_valid_policy_hnd(&group_handle
)) {
3343 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3350 if (is_valid_policy_hnd(&group_handle
)) {
3351 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3354 if (ctx
->disable_policy_handle_cache
) {
3355 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3356 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3362 /****************************************************************
3363 ****************************************************************/
3365 WERROR
NetUserSetGroups_l(struct libnetapi_ctx
*ctx
,
3366 struct NetUserSetGroups
*r
)
3368 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetGroups
);
3371 /****************************************************************
3372 ****************************************************************/
3374 static NTSTATUS
add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
3376 const char *group_name
,
3378 uint32_t *num_entries
)
3380 struct LOCALGROUP_USERS_INFO_0 u0
;
3384 u0
.lgrui0_name
= talloc_strdup(mem_ctx
, group_name
);
3385 NT_STATUS_HAVE_NO_MEMORY(u0
.lgrui0_name
);
3387 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_USERS_INFO_0
, u0
,
3388 (struct LOCALGROUP_USERS_INFO_0
**)buffer
, num_entries
);
3391 return NT_STATUS_INVALID_INFO_CLASS
;
3394 return NT_STATUS_OK
;
3397 /****************************************************************
3398 ****************************************************************/
3400 WERROR
NetUserGetLocalGroups_r(struct libnetapi_ctx
*ctx
,
3401 struct NetUserGetLocalGroups
*r
)
3403 struct rpc_pipe_client
*pipe_cli
= NULL
;
3404 struct policy_handle connect_handle
, domain_handle
, user_handle
,
3406 struct lsa_String lsa_account_name
;
3407 struct dom_sid2
*domain_sid
= NULL
;
3408 struct samr_Ids user_rids
, name_types
;
3409 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3410 struct lsa_Strings names
;
3411 struct samr_Ids types
;
3412 uint32_t *rids
= NULL
;
3413 size_t num_rids
= 0;
3414 struct dom_sid user_sid
;
3415 struct lsa_SidArray sid_array
;
3416 struct samr_Ids domain_rids
;
3417 struct samr_Ids builtin_rids
;
3420 uint32_t entries_read
= 0;
3423 NTSTATUS result
= NT_STATUS_OK
;
3425 struct dcerpc_binding_handle
*b
= NULL
;
3427 ZERO_STRUCT(connect_handle
);
3428 ZERO_STRUCT(domain_handle
);
3430 if (!r
->out
.buffer
) {
3431 return WERR_INVALID_PARAMETER
;
3434 *r
->out
.buffer
= NULL
;
3435 *r
->out
.entries_read
= 0;
3436 *r
->out
.total_entries
= 0;
3438 switch (r
->in
.level
) {
3443 return WERR_INVALID_LEVEL
;
3446 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3449 if (!W_ERROR_IS_OK(werr
)) {
3453 b
= pipe_cli
->binding_handle
;
3455 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3456 SAMR_ACCESS_ENUM_DOMAINS
|
3457 SAMR_ACCESS_LOOKUP_DOMAIN
,
3458 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3459 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3463 if (!W_ERROR_IS_OK(werr
)) {
3467 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
3468 SAMR_ACCESS_ENUM_DOMAINS
|
3469 SAMR_ACCESS_LOOKUP_DOMAIN
,
3470 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3471 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3474 if (!W_ERROR_IS_OK(werr
)) {
3478 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3480 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3487 if (any_nt_status_not_ok(status
, result
, &status
)) {
3488 werr
= ntstatus_to_werror(status
);
3491 if (user_rids
.count
!= 1) {
3492 werr
= WERR_BAD_NET_RESP
;
3495 if (name_types
.count
!= 1) {
3496 werr
= WERR_BAD_NET_RESP
;
3500 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3502 SAMR_USER_ACCESS_GET_GROUPS
,
3506 if (any_nt_status_not_ok(status
, result
, &status
)) {
3507 werr
= ntstatus_to_werror(status
);
3511 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3515 if (any_nt_status_not_ok(status
, result
, &status
)) {
3516 werr
= ntstatus_to_werror(status
);
3520 if (!sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0])) {
3521 werr
= WERR_NOT_ENOUGH_MEMORY
;
3525 sid_array
.num_sids
= rid_array
->count
+ 1;
3526 sid_array
.sids
= talloc_array(ctx
, struct lsa_SidPtr
, sid_array
.num_sids
);
3527 if (!sid_array
.sids
) {
3528 werr
= WERR_NOT_ENOUGH_MEMORY
;
3532 sid_array
.sids
[0].sid
= dom_sid_dup(ctx
, &user_sid
);
3533 if (!sid_array
.sids
[0].sid
) {
3534 werr
= WERR_NOT_ENOUGH_MEMORY
;
3538 for (i
=0; i
< rid_array
->count
; i
++) {
3541 if (!sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
)) {
3542 werr
= WERR_NOT_ENOUGH_MEMORY
;
3546 sid_array
.sids
[i
+1].sid
= dom_sid_dup(ctx
, &sid
);
3547 if (!sid_array
.sids
[i
+1].sid
) {
3548 werr
= WERR_NOT_ENOUGH_MEMORY
;
3553 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3558 if (any_nt_status_not_ok(status
, result
, &status
)) {
3559 werr
= ntstatus_to_werror(status
);
3563 for (i
=0; i
< domain_rids
.count
; i
++) {
3564 if (!add_rid_to_array_unique(ctx
, domain_rids
.ids
[i
],
3565 &rids
, &num_rids
)) {
3566 werr
= WERR_NOT_ENOUGH_MEMORY
;
3571 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3576 if (any_nt_status_not_ok(status
, result
, &status
)) {
3577 werr
= ntstatus_to_werror(status
);
3581 for (i
=0; i
< builtin_rids
.count
; i
++) {
3582 if (!add_rid_to_array_unique(ctx
, builtin_rids
.ids
[i
],
3583 &rids
, &num_rids
)) {
3584 werr
= WERR_NOT_ENOUGH_MEMORY
;
3589 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3596 if (any_nt_status_not_ok(status
, result
, &status
)) {
3597 werr
= ntstatus_to_werror(status
);
3600 if (names
.count
!= num_rids
) {
3601 werr
= WERR_BAD_NET_RESP
;
3604 if (types
.count
!= num_rids
) {
3605 werr
= WERR_BAD_NET_RESP
;
3609 for (i
=0; i
< names
.count
; i
++) {
3610 status
= add_LOCALGROUP_USERS_INFO_X_buffer(ctx
,
3612 names
.names
[i
].string
,
3615 if (!NT_STATUS_IS_OK(status
)) {
3616 werr
= ntstatus_to_werror(status
);
3621 *r
->out
.entries_read
= entries_read
;
3622 *r
->out
.total_entries
= entries_read
;
3625 if (ctx
->disable_policy_handle_cache
) {
3626 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3627 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3633 /****************************************************************
3634 ****************************************************************/
3636 WERROR
NetUserGetLocalGroups_l(struct libnetapi_ctx
*ctx
,
3637 struct NetUserGetLocalGroups
*r
)
3639 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetLocalGroups
);