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
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
481 if (!NT_STATUS_IS_OK(status
)) {
482 werr
= ntstatus_to_werror(status
);
486 uX
.usriX_flags
|= ACB_NORMAL
;
488 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
492 if (!NT_STATUS_IS_OK(status
)) {
493 werr
= ntstatus_to_werror(status
);
501 dcerpc_samr_DeleteUser(b
, talloc_tos(),
506 if (is_valid_policy_hnd(&user_handle
) && b
) {
507 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
510 if (ctx
->disable_policy_handle_cache
) {
511 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
512 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
518 /****************************************************************
519 ****************************************************************/
521 WERROR
NetUserAdd_l(struct libnetapi_ctx
*ctx
,
522 struct NetUserAdd
*r
)
524 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserAdd
);
527 /****************************************************************
528 ****************************************************************/
530 WERROR
NetUserDel_r(struct libnetapi_ctx
*ctx
,
531 struct NetUserDel
*r
)
533 struct rpc_pipe_client
*pipe_cli
= NULL
;
534 NTSTATUS status
, result
;
536 struct policy_handle connect_handle
, builtin_handle
, domain_handle
, user_handle
;
537 struct lsa_String lsa_account_name
;
538 struct samr_Ids user_rids
, name_types
;
539 struct dom_sid2
*domain_sid
= NULL
;
540 struct dom_sid2 user_sid
;
541 struct dcerpc_binding_handle
*b
= NULL
;
543 ZERO_STRUCT(connect_handle
);
544 ZERO_STRUCT(builtin_handle
);
545 ZERO_STRUCT(domain_handle
);
546 ZERO_STRUCT(user_handle
);
548 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
552 if (!W_ERROR_IS_OK(werr
)) {
556 b
= pipe_cli
->binding_handle
;
558 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
559 SAMR_ACCESS_ENUM_DOMAINS
|
560 SAMR_ACCESS_LOOKUP_DOMAIN
,
561 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
565 if (!W_ERROR_IS_OK(werr
)) {
569 status
= dcerpc_samr_OpenDomain(b
, talloc_tos(),
571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
572 discard_const_p(struct dom_sid
, &global_sid_Builtin
),
575 if (any_nt_status_not_ok(status
, result
, &status
)) {
576 werr
= ntstatus_to_werror(status
);
580 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
582 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
589 if (any_nt_status_not_ok(status
, result
, &status
)) {
590 werr
= ntstatus_to_werror(status
);
593 if (user_rids
.count
!= 1) {
594 werr
= WERR_BAD_NET_RESP
;
597 if (name_types
.count
!= 1) {
598 werr
= WERR_BAD_NET_RESP
;
602 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
608 if (any_nt_status_not_ok(status
, result
, &status
)) {
609 werr
= ntstatus_to_werror(status
);
613 sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0]);
615 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, talloc_tos(),
619 if (any_nt_status_not_ok(status
, result
, &status
)) {
620 werr
= ntstatus_to_werror(status
);
624 status
= dcerpc_samr_DeleteUser(b
, talloc_tos(),
627 if (any_nt_status_not_ok(status
, result
, &status
)) {
628 werr
= ntstatus_to_werror(status
);
635 if (is_valid_policy_hnd(&user_handle
)) {
636 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
639 if (ctx
->disable_policy_handle_cache
) {
640 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
641 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
642 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
648 /****************************************************************
649 ****************************************************************/
651 WERROR
NetUserDel_l(struct libnetapi_ctx
*ctx
,
652 struct NetUserDel
*r
)
654 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserDel
);
657 /****************************************************************
658 ****************************************************************/
660 static NTSTATUS
libnetapi_samr_lookup_user(TALLOC_CTX
*mem_ctx
,
661 struct rpc_pipe_client
*pipe_cli
,
662 struct policy_handle
*domain_handle
,
663 struct policy_handle
*builtin_handle
,
664 const char *user_name
,
665 const struct dom_sid
*domain_sid
,
668 struct samr_UserInfo21
**info21
,
669 struct sec_desc_buf
**sec_desc
,
670 uint32_t *auth_flag_p
)
672 NTSTATUS status
, result
;
674 struct policy_handle user_handle
;
675 union samr_UserInfo
*user_info
= NULL
;
676 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
677 uint32_t access_mask
= SEC_STD_READ_CONTROL
|
678 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
679 SAMR_USER_ACCESS_GET_NAME_ETC
;
680 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
682 ZERO_STRUCT(user_handle
);
688 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
689 SAMR_USER_ACCESS_GET_GROUPS
;
695 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
696 SAMR_USER_ACCESS_GET_GROUPS
|
697 SAMR_USER_ACCESS_GET_LOCALE
;
704 return NT_STATUS_INVALID_LEVEL
;
711 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
717 if (any_nt_status_not_ok(status
, result
, &status
)) {
721 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
726 if (any_nt_status_not_ok(status
, result
, &status
)) {
730 status
= dcerpc_samr_QuerySecurity(b
, mem_ctx
,
735 if (any_nt_status_not_ok(status
, result
, &status
)) {
739 if (access_mask
& SAMR_USER_ACCESS_GET_GROUPS
) {
741 struct lsa_SidArray sid_array
;
742 struct samr_Ids alias_rids
;
744 uint32_t auth_flag
= 0;
747 status
= dcerpc_samr_GetGroupsForUser(b
, mem_ctx
,
751 if (any_nt_status_not_ok(status
, result
, &status
)) {
755 sid_array
.num_sids
= rid_array
->count
+ 1;
756 sid_array
.sids
= talloc_array(mem_ctx
, struct lsa_SidPtr
,
758 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
);
760 for (i
=0; i
<rid_array
->count
; i
++) {
761 sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
);
762 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
763 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
766 sid_compose(&sid
, domain_sid
, rid
);
767 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
768 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
770 status
= dcerpc_samr_GetAliasMembership(b
, mem_ctx
,
775 if (any_nt_status_not_ok(status
, result
, &status
)) {
779 for (i
=0; i
<alias_rids
.count
; i
++) {
780 switch (alias_rids
.ids
[i
]) {
781 case 550: /* Print Operators */
782 auth_flag
|= AF_OP_PRINT
;
784 case 549: /* Server Operators */
785 auth_flag
|= AF_OP_SERVER
;
787 case 548: /* Account Operators */
788 auth_flag
|= AF_OP_ACCOUNTS
;
796 *auth_flag_p
= auth_flag
;
800 *info21
= &user_info
->info21
;
803 if (is_valid_policy_hnd(&user_handle
)) {
804 dcerpc_samr_Close(b
, mem_ctx
, &user_handle
, &result
);
810 /****************************************************************
811 ****************************************************************/
813 static uint32_t samr_rid_to_priv_level(uint32_t rid
)
816 case DOMAIN_RID_ADMINISTRATOR
:
817 return USER_PRIV_ADMIN
;
818 case DOMAIN_RID_GUEST
:
819 return USER_PRIV_GUEST
;
821 return USER_PRIV_USER
;
825 /****************************************************************
826 ****************************************************************/
828 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb
)
830 uint32_t fl
= UF_SCRIPT
; /* god knows why */
832 fl
|= ds_acb2uf(acb
);
837 /****************************************************************
838 ****************************************************************/
840 static NTSTATUS
info21_to_USER_INFO_1(TALLOC_CTX
*mem_ctx
,
841 const struct samr_UserInfo21
*i21
,
842 struct USER_INFO_1
*i
)
845 i
->usri1_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
846 NT_STATUS_HAVE_NO_MEMORY(i
->usri1_name
);
847 i
->usri1_password
= NULL
;
848 i
->usri1_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
849 i
->usri1_priv
= samr_rid_to_priv_level(i21
->rid
);
850 i
->usri1_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
851 i
->usri1_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
852 i
->usri1_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
853 i
->usri1_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
858 /****************************************************************
859 ****************************************************************/
861 static NTSTATUS
info21_to_USER_INFO_2(TALLOC_CTX
*mem_ctx
,
862 const struct samr_UserInfo21
*i21
,
864 struct USER_INFO_2
*i
)
868 i
->usri2_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
869 NT_STATUS_HAVE_NO_MEMORY(i
->usri2_name
);
870 i
->usri2_password
= NULL
;
871 i
->usri2_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
872 i
->usri2_priv
= samr_rid_to_priv_level(i21
->rid
);
873 i
->usri2_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
874 i
->usri2_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
875 i
->usri2_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
876 i
->usri2_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
877 i
->usri2_auth_flags
= auth_flag
;
878 i
->usri2_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
879 i
->usri2_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
880 i
->usri2_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
881 i
->usri2_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
882 i
->usri2_last_logon
= nt_time_to_unix(i21
->last_logon
);
883 i
->usri2_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
884 i
->usri2_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
885 i
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
886 i
->usri2_units_per_week
= i21
->logon_hours
.units_per_week
;
887 i
->usri2_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
888 i
->usri2_bad_pw_count
= i21
->bad_password_count
;
889 i
->usri2_num_logons
= i21
->logon_count
;
890 i
->usri2_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
891 i
->usri2_country_code
= i21
->country_code
;
892 i
->usri2_code_page
= i21
->code_page
;
897 /****************************************************************
898 ****************************************************************/
900 static NTSTATUS
info21_to_USER_INFO_3(TALLOC_CTX
*mem_ctx
,
901 const struct samr_UserInfo21
*i21
,
903 struct USER_INFO_3
*i
)
907 i
->usri3_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
908 NT_STATUS_HAVE_NO_MEMORY(i
->usri3_name
);
909 i
->usri3_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
910 i
->usri3_priv
= samr_rid_to_priv_level(i21
->rid
);
911 i
->usri3_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
912 i
->usri3_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
913 i
->usri3_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
914 i
->usri3_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
915 i
->usri3_auth_flags
= auth_flag
;
916 i
->usri3_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
917 i
->usri3_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
918 i
->usri3_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
919 i
->usri3_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
920 i
->usri3_last_logon
= nt_time_to_unix(i21
->last_logon
);
921 i
->usri3_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
922 i
->usri3_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
923 i
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
924 i
->usri3_units_per_week
= i21
->logon_hours
.units_per_week
;
925 i
->usri3_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
926 i
->usri3_bad_pw_count
= i21
->bad_password_count
;
927 i
->usri3_num_logons
= i21
->logon_count
;
928 i
->usri3_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
929 i
->usri3_country_code
= i21
->country_code
;
930 i
->usri3_code_page
= i21
->code_page
;
931 i
->usri3_user_id
= i21
->rid
;
932 i
->usri3_primary_group_id
= i21
->primary_gid
;
933 i
->usri3_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
934 i
->usri3_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
935 i
->usri3_password_expired
= i21
->password_expired
;
940 /****************************************************************
941 ****************************************************************/
943 static NTSTATUS
info21_to_USER_INFO_4(TALLOC_CTX
*mem_ctx
,
944 const struct samr_UserInfo21
*i21
,
946 struct dom_sid
*domain_sid
,
947 struct USER_INFO_4
*i
)
953 i
->usri4_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
954 NT_STATUS_HAVE_NO_MEMORY(i
->usri4_name
);
955 i
->usri4_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
956 i
->usri4_password
= NULL
;
957 i
->usri4_priv
= samr_rid_to_priv_level(i21
->rid
);
958 i
->usri4_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
959 i
->usri4_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
960 i
->usri4_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
961 i
->usri4_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
962 i
->usri4_auth_flags
= auth_flag
;
963 i
->usri4_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
964 i
->usri4_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
965 i
->usri4_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
966 i
->usri4_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
967 i
->usri4_last_logon
= nt_time_to_unix(i21
->last_logon
);
968 i
->usri4_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
969 i
->usri4_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
970 i
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
971 i
->usri4_units_per_week
= i21
->logon_hours
.units_per_week
;
972 i
->usri4_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
973 i
->usri4_bad_pw_count
= i21
->bad_password_count
;
974 i
->usri4_num_logons
= i21
->logon_count
;
975 i
->usri4_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
976 i
->usri4_country_code
= i21
->country_code
;
977 i
->usri4_code_page
= i21
->code_page
;
978 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
979 return NT_STATUS_NO_MEMORY
;
981 i
->usri4_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
982 i
->usri4_primary_group_id
= i21
->primary_gid
;
983 i
->usri4_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
984 i
->usri4_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
985 i
->usri4_password_expired
= i21
->password_expired
;
990 /****************************************************************
991 ****************************************************************/
993 static NTSTATUS
info21_to_USER_INFO_10(TALLOC_CTX
*mem_ctx
,
994 const struct samr_UserInfo21
*i21
,
995 struct USER_INFO_10
*i
)
999 i
->usri10_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1000 NT_STATUS_HAVE_NO_MEMORY(i
->usri10_name
);
1001 i
->usri10_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1002 i
->usri10_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1003 i
->usri10_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1005 return NT_STATUS_OK
;
1008 /****************************************************************
1009 ****************************************************************/
1011 static NTSTATUS
info21_to_USER_INFO_11(TALLOC_CTX
*mem_ctx
,
1012 const struct samr_UserInfo21
*i21
,
1014 struct USER_INFO_11
*i
)
1018 i
->usri11_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1019 NT_STATUS_HAVE_NO_MEMORY(i
->usri11_name
);
1020 i
->usri11_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1021 i
->usri11_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1022 i
->usri11_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1023 i
->usri11_priv
= samr_rid_to_priv_level(i21
->rid
);
1024 i
->usri11_auth_flags
= auth_flag
;
1025 i
->usri11_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
1026 i
->usri11_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
1027 i
->usri11_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1028 i
->usri11_last_logon
= nt_time_to_unix(i21
->last_logon
);
1029 i
->usri11_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1030 i
->usri11_bad_pw_count
= i21
->bad_password_count
;
1031 i
->usri11_num_logons
= i21
->logon_count
;
1032 i
->usri11_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1033 i
->usri11_country_code
= i21
->country_code
;
1034 i
->usri11_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1035 i
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1036 i
->usri11_units_per_week
= i21
->logon_hours
.units_per_week
;
1037 i
->usri11_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1038 i
->usri11_code_page
= i21
->code_page
;
1040 return NT_STATUS_OK
;
1043 /****************************************************************
1044 ****************************************************************/
1046 static NTSTATUS
info21_to_USER_INFO_20(TALLOC_CTX
*mem_ctx
,
1047 const struct samr_UserInfo21
*i21
,
1048 struct USER_INFO_20
*i
)
1052 i
->usri20_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1053 NT_STATUS_HAVE_NO_MEMORY(i
->usri20_name
);
1054 i
->usri20_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1055 i
->usri20_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1056 i
->usri20_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1057 i
->usri20_user_id
= i21
->rid
;
1059 return NT_STATUS_OK
;
1062 /****************************************************************
1063 ****************************************************************/
1065 static NTSTATUS
info21_to_USER_INFO_23(TALLOC_CTX
*mem_ctx
,
1066 const struct samr_UserInfo21
*i21
,
1067 struct dom_sid
*domain_sid
,
1068 struct USER_INFO_23
*i
)
1074 i
->usri23_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1075 NT_STATUS_HAVE_NO_MEMORY(i
->usri23_name
);
1076 i
->usri23_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1077 i
->usri23_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1078 i
->usri23_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1079 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1080 return NT_STATUS_NO_MEMORY
;
1082 i
->usri23_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1084 return NT_STATUS_OK
;
1087 /****************************************************************
1088 ****************************************************************/
1090 static NTSTATUS
libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX
*mem_ctx
,
1091 struct rpc_pipe_client
*pipe_cli
,
1092 struct dom_sid
*domain_sid
,
1093 struct policy_handle
*domain_handle
,
1094 struct policy_handle
*builtin_handle
,
1095 const char *user_name
,
1099 uint32_t *num_entries
)
1103 struct samr_UserInfo21
*info21
= NULL
;
1104 struct sec_desc_buf
*sec_desc
= NULL
;
1105 uint32_t auth_flag
= 0;
1107 struct USER_INFO_0 info0
;
1108 struct USER_INFO_1 info1
;
1109 struct USER_INFO_2 info2
;
1110 struct USER_INFO_3 info3
;
1111 struct USER_INFO_4 info4
;
1112 struct USER_INFO_10 info10
;
1113 struct USER_INFO_11 info11
;
1114 struct USER_INFO_20 info20
;
1115 struct USER_INFO_23 info23
;
1129 return NT_STATUS_INVALID_LEVEL
;
1133 info0
.usri0_name
= talloc_strdup(mem_ctx
, user_name
);
1134 NT_STATUS_HAVE_NO_MEMORY(info0
.usri0_name
);
1136 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_0
, info0
,
1137 (struct USER_INFO_0
**)buffer
, num_entries
);
1139 return NT_STATUS_OK
;
1142 status
= libnetapi_samr_lookup_user(mem_ctx
, pipe_cli
,
1153 if (!NT_STATUS_IS_OK(status
)) {
1159 status
= info21_to_USER_INFO_1(mem_ctx
, info21
, &info1
);
1160 NT_STATUS_NOT_OK_RETURN(status
);
1162 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_1
, info1
,
1163 (struct USER_INFO_1
**)buffer
, num_entries
);
1167 status
= info21_to_USER_INFO_2(mem_ctx
, info21
, auth_flag
, &info2
);
1168 NT_STATUS_NOT_OK_RETURN(status
);
1170 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_2
, info2
,
1171 (struct USER_INFO_2
**)buffer
, num_entries
);
1175 status
= info21_to_USER_INFO_3(mem_ctx
, info21
, auth_flag
, &info3
);
1176 NT_STATUS_NOT_OK_RETURN(status
);
1178 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_3
, info3
,
1179 (struct USER_INFO_3
**)buffer
, num_entries
);
1183 status
= info21_to_USER_INFO_4(mem_ctx
, info21
, auth_flag
, domain_sid
, &info4
);
1184 NT_STATUS_NOT_OK_RETURN(status
);
1186 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_4
, info4
,
1187 (struct USER_INFO_4
**)buffer
, num_entries
);
1191 status
= info21_to_USER_INFO_10(mem_ctx
, info21
, &info10
);
1192 NT_STATUS_NOT_OK_RETURN(status
);
1194 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_10
, info10
,
1195 (struct USER_INFO_10
**)buffer
, num_entries
);
1199 status
= info21_to_USER_INFO_11(mem_ctx
, info21
, auth_flag
, &info11
);
1200 NT_STATUS_NOT_OK_RETURN(status
);
1202 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_11
, info11
,
1203 (struct USER_INFO_11
**)buffer
, num_entries
);
1207 status
= info21_to_USER_INFO_20(mem_ctx
, info21
, &info20
);
1208 NT_STATUS_NOT_OK_RETURN(status
);
1210 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_20
, info20
,
1211 (struct USER_INFO_20
**)buffer
, num_entries
);
1215 status
= info21_to_USER_INFO_23(mem_ctx
, info21
, domain_sid
, &info23
);
1216 NT_STATUS_NOT_OK_RETURN(status
);
1218 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_23
, info23
,
1219 (struct USER_INFO_23
**)buffer
, num_entries
);
1222 return NT_STATUS_INVALID_LEVEL
;
1229 /****************************************************************
1230 ****************************************************************/
1232 WERROR
NetUserEnum_r(struct libnetapi_ctx
*ctx
,
1233 struct NetUserEnum
*r
)
1235 struct rpc_pipe_client
*pipe_cli
= NULL
;
1236 struct policy_handle connect_handle
;
1237 struct dom_sid2
*domain_sid
= NULL
;
1238 struct policy_handle domain_handle
, builtin_handle
;
1239 struct samr_SamArray
*sam
= NULL
;
1240 uint32_t filter
= ACB_NORMAL
;
1242 uint32_t entries_read
= 0;
1245 NTSTATUS result
= NT_STATUS_OK
;
1247 struct dcerpc_binding_handle
*b
= NULL
;
1249 ZERO_STRUCT(connect_handle
);
1250 ZERO_STRUCT(domain_handle
);
1251 ZERO_STRUCT(builtin_handle
);
1253 if (!r
->out
.buffer
) {
1254 return WERR_INVALID_PARAMETER
;
1257 *r
->out
.buffer
= NULL
;
1258 *r
->out
.entries_read
= 0;
1260 switch (r
->in
.level
) {
1272 return WERR_INVALID_LEVEL
;
1275 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1278 if (!W_ERROR_IS_OK(werr
)) {
1282 b
= pipe_cli
->binding_handle
;
1284 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1285 SAMR_ACCESS_ENUM_DOMAINS
|
1286 SAMR_ACCESS_LOOKUP_DOMAIN
,
1287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1288 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1291 if (!W_ERROR_IS_OK(werr
)) {
1295 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1296 SAMR_ACCESS_ENUM_DOMAINS
|
1297 SAMR_ACCESS_LOOKUP_DOMAIN
,
1298 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1299 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1300 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1304 if (!W_ERROR_IS_OK(werr
)) {
1308 switch (r
->in
.filter
) {
1309 case FILTER_NORMAL_ACCOUNT
:
1310 filter
= ACB_NORMAL
;
1312 case FILTER_TEMP_DUPLICATE_ACCOUNT
:
1313 filter
= ACB_TEMPDUP
;
1315 case FILTER_INTERDOMAIN_TRUST_ACCOUNT
:
1316 filter
= ACB_DOMTRUST
;
1318 case FILTER_WORKSTATION_TRUST_ACCOUNT
:
1319 filter
= ACB_WSTRUST
;
1321 case FILTER_SERVER_TRUST_ACCOUNT
:
1322 filter
= ACB_SVRTRUST
;
1328 status
= dcerpc_samr_EnumDomainUsers(b
,
1331 r
->in
.resume_handle
,
1337 if (!NT_STATUS_IS_OK(status
)) {
1338 werr
= ntstatus_to_werror(status
);
1341 werr
= ntstatus_to_werror(result
);
1342 if (NT_STATUS_IS_ERR(result
)) {
1346 for (i
=0; i
< sam
->count
; i
++) {
1348 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1352 sam
->entries
[i
].name
.string
,
1353 sam
->entries
[i
].idx
,
1356 r
->out
.entries_read
);
1357 if (!NT_STATUS_IS_OK(status
)) {
1358 werr
= ntstatus_to_werror(status
);
1365 if (NT_STATUS_IS_OK(result
) ||
1366 NT_STATUS_IS_ERR(result
)) {
1368 if (ctx
->disable_policy_handle_cache
) {
1369 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1370 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1371 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1378 /****************************************************************
1379 ****************************************************************/
1381 WERROR
NetUserEnum_l(struct libnetapi_ctx
*ctx
,
1382 struct NetUserEnum
*r
)
1384 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserEnum
);
1387 /****************************************************************
1388 ****************************************************************/
1390 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX
*mem_ctx
,
1391 struct samr_DispInfoGeneral
*info
,
1392 uint32_t *entries_read
,
1395 struct NET_DISPLAY_USER
*user
= NULL
;
1398 user
= talloc_zero_array(mem_ctx
,
1399 struct NET_DISPLAY_USER
,
1401 W_ERROR_HAVE_NO_MEMORY(user
);
1403 for (i
= 0; i
< info
->count
; i
++) {
1404 user
[i
].usri1_name
= talloc_strdup(mem_ctx
,
1405 info
->entries
[i
].account_name
.string
);
1406 user
[i
].usri1_comment
= talloc_strdup(mem_ctx
,
1407 info
->entries
[i
].description
.string
);
1408 user
[i
].usri1_flags
=
1409 info
->entries
[i
].acct_flags
;
1410 user
[i
].usri1_full_name
= talloc_strdup(mem_ctx
,
1411 info
->entries
[i
].full_name
.string
);
1412 user
[i
].usri1_user_id
=
1413 info
->entries
[i
].rid
;
1414 user
[i
].usri1_next_index
=
1415 info
->entries
[i
].idx
;
1417 if (!user
[i
].usri1_name
) {
1418 return WERR_NOT_ENOUGH_MEMORY
;
1422 *buffer
= talloc_memdup(mem_ctx
, user
,
1423 sizeof(struct NET_DISPLAY_USER
) * info
->count
);
1424 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1426 *entries_read
= info
->count
;
1431 /****************************************************************
1432 ****************************************************************/
1434 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX
*mem_ctx
,
1435 struct samr_DispInfoFull
*info
,
1436 uint32_t *entries_read
,
1439 struct NET_DISPLAY_MACHINE
*machine
= NULL
;
1442 machine
= talloc_zero_array(mem_ctx
,
1443 struct NET_DISPLAY_MACHINE
,
1445 W_ERROR_HAVE_NO_MEMORY(machine
);
1447 for (i
= 0; i
< info
->count
; i
++) {
1448 machine
[i
].usri2_name
= talloc_strdup(mem_ctx
,
1449 info
->entries
[i
].account_name
.string
);
1450 machine
[i
].usri2_comment
= talloc_strdup(mem_ctx
,
1451 info
->entries
[i
].description
.string
);
1452 machine
[i
].usri2_flags
=
1453 info
->entries
[i
].acct_flags
;
1454 machine
[i
].usri2_user_id
=
1455 info
->entries
[i
].rid
;
1456 machine
[i
].usri2_next_index
=
1457 info
->entries
[i
].idx
;
1459 if (!machine
[i
].usri2_name
) {
1460 return WERR_NOT_ENOUGH_MEMORY
;
1464 *buffer
= talloc_memdup(mem_ctx
, machine
,
1465 sizeof(struct NET_DISPLAY_MACHINE
) * info
->count
);
1466 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1468 *entries_read
= info
->count
;
1473 /****************************************************************
1474 ****************************************************************/
1476 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX
*mem_ctx
,
1477 struct samr_DispInfoFullGroups
*info
,
1478 uint32_t *entries_read
,
1481 struct NET_DISPLAY_GROUP
*group
= NULL
;
1484 group
= talloc_zero_array(mem_ctx
,
1485 struct NET_DISPLAY_GROUP
,
1487 W_ERROR_HAVE_NO_MEMORY(group
);
1489 for (i
= 0; i
< info
->count
; i
++) {
1490 group
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1491 info
->entries
[i
].account_name
.string
);
1492 group
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1493 info
->entries
[i
].description
.string
);
1494 group
[i
].grpi3_group_id
=
1495 info
->entries
[i
].rid
;
1496 group
[i
].grpi3_attributes
=
1497 info
->entries
[i
].acct_flags
;
1498 group
[i
].grpi3_next_index
=
1499 info
->entries
[i
].idx
;
1501 if (!group
[i
].grpi3_name
) {
1502 return WERR_NOT_ENOUGH_MEMORY
;
1506 *buffer
= talloc_memdup(mem_ctx
, group
,
1507 sizeof(struct NET_DISPLAY_GROUP
) * info
->count
);
1508 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1510 *entries_read
= info
->count
;
1516 /****************************************************************
1517 ****************************************************************/
1519 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX
*mem_ctx
,
1520 union samr_DispInfo
*info
,
1522 uint32_t *entries_read
,
1527 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx
,
1532 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx
,
1537 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx
,
1545 return WERR_INVALID_LEVEL
;
1548 /****************************************************************
1549 ****************************************************************/
1551 WERROR
NetQueryDisplayInformation_r(struct libnetapi_ctx
*ctx
,
1552 struct NetQueryDisplayInformation
*r
)
1554 struct rpc_pipe_client
*pipe_cli
= NULL
;
1555 struct policy_handle connect_handle
;
1556 struct dom_sid2
*domain_sid
= NULL
;
1557 struct policy_handle domain_handle
;
1558 union samr_DispInfo info
;
1559 struct dcerpc_binding_handle
*b
= NULL
;
1561 uint32_t total_size
= 0;
1562 uint32_t returned_size
= 0;
1565 NTSTATUS result
= NT_STATUS_OK
;
1569 *r
->out
.entries_read
= 0;
1571 ZERO_STRUCT(connect_handle
);
1572 ZERO_STRUCT(domain_handle
);
1574 switch (r
->in
.level
) {
1580 return WERR_INVALID_LEVEL
;
1583 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1586 if (!W_ERROR_IS_OK(werr
)) {
1590 b
= pipe_cli
->binding_handle
;
1592 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1593 SAMR_ACCESS_ENUM_DOMAINS
|
1594 SAMR_ACCESS_LOOKUP_DOMAIN
,
1595 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1596 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1597 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1601 if (!W_ERROR_IS_OK(werr
)) {
1605 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1610 r
->in
.entries_requested
,
1616 if (!NT_STATUS_IS_OK(status
)) {
1617 werr
= ntstatus_to_werror(status
);
1620 werr
= ntstatus_to_werror(result
);
1621 if (NT_STATUS_IS_ERR(result
)) {
1625 werr_tmp
= convert_samr_dispinfo_to_NET_DISPLAY(ctx
, &info
,
1627 r
->out
.entries_read
,
1629 if (!W_ERROR_IS_OK(werr_tmp
)) {
1634 if (NT_STATUS_IS_OK(result
) ||
1635 NT_STATUS_IS_ERR(result
)) {
1637 if (ctx
->disable_policy_handle_cache
) {
1638 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1639 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1647 /****************************************************************
1648 ****************************************************************/
1651 WERROR
NetQueryDisplayInformation_l(struct libnetapi_ctx
*ctx
,
1652 struct NetQueryDisplayInformation
*r
)
1654 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetQueryDisplayInformation
);
1657 /****************************************************************
1658 ****************************************************************/
1660 WERROR
NetUserChangePassword_r(struct libnetapi_ctx
*ctx
,
1661 struct NetUserChangePassword
*r
)
1663 return WERR_NOT_SUPPORTED
;
1666 /****************************************************************
1667 ****************************************************************/
1669 WERROR
NetUserChangePassword_l(struct libnetapi_ctx
*ctx
,
1670 struct NetUserChangePassword
*r
)
1672 return WERR_NOT_SUPPORTED
;
1675 /****************************************************************
1676 ****************************************************************/
1678 WERROR
NetUserGetInfo_r(struct libnetapi_ctx
*ctx
,
1679 struct NetUserGetInfo
*r
)
1681 struct rpc_pipe_client
*pipe_cli
= NULL
;
1682 NTSTATUS status
, result
;
1685 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1686 struct lsa_String lsa_account_name
;
1687 struct dom_sid2
*domain_sid
= NULL
;
1688 struct samr_Ids user_rids
, name_types
;
1689 uint32_t num_entries
= 0;
1690 struct dcerpc_binding_handle
*b
= NULL
;
1692 ZERO_STRUCT(connect_handle
);
1693 ZERO_STRUCT(domain_handle
);
1694 ZERO_STRUCT(builtin_handle
);
1695 ZERO_STRUCT(user_handle
);
1697 if (!r
->out
.buffer
) {
1698 return WERR_INVALID_PARAMETER
;
1701 switch (r
->in
.level
) {
1713 werr
= WERR_INVALID_LEVEL
;
1717 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1720 if (!W_ERROR_IS_OK(werr
)) {
1724 b
= pipe_cli
->binding_handle
;
1726 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1727 SAMR_ACCESS_ENUM_DOMAINS
|
1728 SAMR_ACCESS_LOOKUP_DOMAIN
,
1729 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1733 if (!W_ERROR_IS_OK(werr
)) {
1737 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1738 SAMR_ACCESS_ENUM_DOMAINS
|
1739 SAMR_ACCESS_LOOKUP_DOMAIN
,
1740 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1741 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1744 if (!W_ERROR_IS_OK(werr
)) {
1748 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1750 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1757 if (any_nt_status_not_ok(status
, result
, &status
)) {
1758 werr
= ntstatus_to_werror(status
);
1761 if (user_rids
.count
!= 1) {
1762 werr
= WERR_BAD_NET_RESP
;
1765 if (name_types
.count
!= 1) {
1766 werr
= WERR_BAD_NET_RESP
;
1770 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1779 if (!NT_STATUS_IS_OK(status
)) {
1780 werr
= ntstatus_to_werror(status
);
1785 if (is_valid_policy_hnd(&user_handle
) && b
) {
1786 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1789 if (ctx
->disable_policy_handle_cache
) {
1790 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1791 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1797 /****************************************************************
1798 ****************************************************************/
1800 WERROR
NetUserGetInfo_l(struct libnetapi_ctx
*ctx
,
1801 struct NetUserGetInfo
*r
)
1803 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetInfo
);
1806 /****************************************************************
1807 ****************************************************************/
1809 WERROR
NetUserSetInfo_r(struct libnetapi_ctx
*ctx
,
1810 struct NetUserSetInfo
*r
)
1812 struct rpc_pipe_client
*pipe_cli
= NULL
;
1813 NTSTATUS status
, result
;
1816 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1817 struct lsa_String lsa_account_name
;
1818 struct dom_sid2
*domain_sid
= NULL
;
1819 struct samr_Ids user_rids
, name_types
;
1820 uint32_t user_mask
= 0;
1822 struct USER_INFO_X uX
;
1823 struct dcerpc_binding_handle
*b
= NULL
;
1824 DATA_BLOB session_key
;
1826 ZERO_STRUCT(connect_handle
);
1827 ZERO_STRUCT(domain_handle
);
1828 ZERO_STRUCT(builtin_handle
);
1829 ZERO_STRUCT(user_handle
);
1831 if (!r
->in
.buffer
) {
1832 return WERR_INVALID_PARAMETER
;
1835 switch (r
->in
.level
) {
1837 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1840 user_mask
= SAMR_USER_ACCESS_SET_PASSWORD
;
1849 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1853 user_mask
= SAMR_USER_ACCESS_SET_LOC_COM
;
1856 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1857 SAMR_USER_ACCESS_GET_GROUPS
;
1860 user_mask
= SEC_STD_READ_CONTROL
|
1862 SAMR_USER_ACCESS_GET_GROUPS
|
1863 SAMR_USER_ACCESS_SET_PASSWORD
|
1864 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1865 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
1866 SAMR_USER_ACCESS_SET_LOC_COM
;
1878 werr
= WERR_NOT_SUPPORTED
;
1881 werr
= WERR_INVALID_LEVEL
;
1885 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1888 if (!W_ERROR_IS_OK(werr
)) {
1892 b
= pipe_cli
->binding_handle
;
1894 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1895 SAMR_ACCESS_ENUM_DOMAINS
|
1896 SAMR_ACCESS_LOOKUP_DOMAIN
,
1897 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
1898 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1902 if (!W_ERROR_IS_OK(werr
)) {
1906 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1907 SAMR_ACCESS_ENUM_DOMAINS
|
1908 SAMR_ACCESS_LOOKUP_DOMAIN
,
1909 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1910 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1913 if (!W_ERROR_IS_OK(werr
)) {
1917 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1919 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1926 if (any_nt_status_not_ok(status
, result
, &status
)) {
1927 werr
= ntstatus_to_werror(status
);
1930 if (user_rids
.count
!= 1) {
1931 werr
= WERR_BAD_NET_RESP
;
1934 if (name_types
.count
!= 1) {
1935 werr
= WERR_BAD_NET_RESP
;
1939 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
1945 if (any_nt_status_not_ok(status
, result
, &status
)) {
1946 werr
= ntstatus_to_werror(status
);
1950 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
1951 if (!NT_STATUS_IS_OK(status
)) {
1952 werr
= ntstatus_to_werror(status
);
1956 status
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
1957 if (!NT_STATUS_IS_OK(status
)) {
1958 werr
= ntstatus_to_werror(status
);
1962 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
1966 if (!NT_STATUS_IS_OK(status
)) {
1967 werr
= ntstatus_to_werror(status
);
1974 if (is_valid_policy_hnd(&user_handle
) && b
) {
1975 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1978 if (ctx
->disable_policy_handle_cache
) {
1979 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1980 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1981 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1987 /****************************************************************
1988 ****************************************************************/
1990 WERROR
NetUserSetInfo_l(struct libnetapi_ctx
*ctx
,
1991 struct NetUserSetInfo
*r
)
1993 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetInfo
);
1996 /****************************************************************
1997 ****************************************************************/
1999 static NTSTATUS
query_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2000 struct rpc_pipe_client
*pipe_cli
,
2001 struct policy_handle
*domain_handle
,
2002 struct samr_DomInfo1
*info1
,
2003 struct samr_DomInfo3
*info3
,
2004 struct samr_DomInfo5
*info5
,
2005 struct samr_DomInfo6
*info6
,
2006 struct samr_DomInfo7
*info7
,
2007 struct samr_DomInfo12
*info12
)
2009 NTSTATUS status
, result
;
2010 union samr_DomainInfo
*dom_info
= NULL
;
2011 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2014 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2019 NT_STATUS_NOT_OK_RETURN(status
);
2020 NT_STATUS_NOT_OK_RETURN(result
);
2022 *info1
= dom_info
->info1
;
2026 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2031 NT_STATUS_NOT_OK_RETURN(status
);
2032 NT_STATUS_NOT_OK_RETURN(result
);
2034 *info3
= dom_info
->info3
;
2038 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2043 NT_STATUS_NOT_OK_RETURN(status
);
2044 NT_STATUS_NOT_OK_RETURN(result
);
2046 *info5
= dom_info
->info5
;
2050 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2055 NT_STATUS_NOT_OK_RETURN(status
);
2056 NT_STATUS_NOT_OK_RETURN(result
);
2058 *info6
= dom_info
->info6
;
2062 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2067 NT_STATUS_NOT_OK_RETURN(status
);
2068 NT_STATUS_NOT_OK_RETURN(result
);
2070 *info7
= dom_info
->info7
;
2074 status
= dcerpc_samr_QueryDomainInfo2(b
, mem_ctx
,
2079 NT_STATUS_NOT_OK_RETURN(status
);
2080 NT_STATUS_NOT_OK_RETURN(result
);
2082 *info12
= dom_info
->info12
;
2085 return NT_STATUS_OK
;
2088 /****************************************************************
2089 ****************************************************************/
2091 static NTSTATUS
query_USER_MODALS_INFO_0(TALLOC_CTX
*mem_ctx
,
2092 struct rpc_pipe_client
*pipe_cli
,
2093 struct policy_handle
*domain_handle
,
2094 struct USER_MODALS_INFO_0
*info0
)
2097 struct samr_DomInfo1 dom_info1
;
2098 struct samr_DomInfo3 dom_info3
;
2100 ZERO_STRUCTP(info0
);
2102 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2111 NT_STATUS_NOT_OK_RETURN(status
);
2113 info0
->usrmod0_min_passwd_len
=
2114 dom_info1
.min_password_length
;
2115 info0
->usrmod0_max_passwd_age
=
2116 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.max_password_age
);
2117 info0
->usrmod0_min_passwd_age
=
2118 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.min_password_age
);
2119 info0
->usrmod0_password_hist_len
=
2120 dom_info1
.password_history_length
;
2122 info0
->usrmod0_force_logoff
=
2123 nt_time_to_unix_abs(&dom_info3
.force_logoff_time
);
2125 return NT_STATUS_OK
;
2128 /****************************************************************
2129 ****************************************************************/
2131 static NTSTATUS
query_USER_MODALS_INFO_1(TALLOC_CTX
*mem_ctx
,
2132 struct rpc_pipe_client
*pipe_cli
,
2133 struct policy_handle
*domain_handle
,
2134 struct USER_MODALS_INFO_1
*info1
)
2137 struct samr_DomInfo6 dom_info6
;
2138 struct samr_DomInfo7 dom_info7
;
2140 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2149 NT_STATUS_NOT_OK_RETURN(status
);
2151 info1
->usrmod1_primary
=
2152 talloc_strdup(mem_ctx
, dom_info6
.primary
.string
);
2154 info1
->usrmod1_role
= dom_info7
.role
;
2156 return NT_STATUS_OK
;
2159 /****************************************************************
2160 ****************************************************************/
2162 static NTSTATUS
query_USER_MODALS_INFO_2(TALLOC_CTX
*mem_ctx
,
2163 struct rpc_pipe_client
*pipe_cli
,
2164 struct policy_handle
*domain_handle
,
2165 struct dom_sid
*domain_sid
,
2166 struct USER_MODALS_INFO_2
*info2
)
2169 struct samr_DomInfo5 dom_info5
;
2171 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2180 NT_STATUS_NOT_OK_RETURN(status
);
2182 info2
->usrmod2_domain_name
=
2183 talloc_strdup(mem_ctx
, dom_info5
.domain_name
.string
);
2184 info2
->usrmod2_domain_id
=
2185 (struct domsid
*)dom_sid_dup(mem_ctx
, domain_sid
);
2187 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_name
);
2188 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_id
);
2190 return NT_STATUS_OK
;
2193 /****************************************************************
2194 ****************************************************************/
2196 static NTSTATUS
query_USER_MODALS_INFO_3(TALLOC_CTX
*mem_ctx
,
2197 struct rpc_pipe_client
*pipe_cli
,
2198 struct policy_handle
*domain_handle
,
2199 struct USER_MODALS_INFO_3
*info3
)
2202 struct samr_DomInfo12 dom_info12
;
2204 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2213 NT_STATUS_NOT_OK_RETURN(status
);
2215 info3
->usrmod3_lockout_duration
=
2216 nt_time_to_unix_abs(&dom_info12
.lockout_duration
);
2217 info3
->usrmod3_lockout_observation_window
=
2218 nt_time_to_unix_abs(&dom_info12
.lockout_window
);
2219 info3
->usrmod3_lockout_threshold
=
2220 dom_info12
.lockout_threshold
;
2222 return NT_STATUS_OK
;
2225 /****************************************************************
2226 ****************************************************************/
2228 static NTSTATUS
query_USER_MODALS_INFO_to_buffer(TALLOC_CTX
*mem_ctx
,
2229 struct rpc_pipe_client
*pipe_cli
,
2231 struct policy_handle
*domain_handle
,
2232 struct dom_sid
*domain_sid
,
2237 struct USER_MODALS_INFO_0 info0
;
2238 struct USER_MODALS_INFO_1 info1
;
2239 struct USER_MODALS_INFO_2 info2
;
2240 struct USER_MODALS_INFO_3 info3
;
2243 return ERROR_INSUFFICIENT_BUFFER
;
2248 status
= query_USER_MODALS_INFO_0(mem_ctx
,
2252 NT_STATUS_NOT_OK_RETURN(status
);
2254 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
,
2259 status
= query_USER_MODALS_INFO_1(mem_ctx
,
2263 NT_STATUS_NOT_OK_RETURN(status
);
2265 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
,
2269 status
= query_USER_MODALS_INFO_2(mem_ctx
,
2274 NT_STATUS_NOT_OK_RETURN(status
);
2276 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
,
2280 status
= query_USER_MODALS_INFO_3(mem_ctx
,
2284 NT_STATUS_NOT_OK_RETURN(status
);
2286 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
,
2293 NT_STATUS_HAVE_NO_MEMORY(*buffer
);
2295 return NT_STATUS_OK
;
2298 /****************************************************************
2299 ****************************************************************/
2301 WERROR
NetUserModalsGet_r(struct libnetapi_ctx
*ctx
,
2302 struct NetUserModalsGet
*r
)
2304 struct rpc_pipe_client
*pipe_cli
= NULL
;
2308 struct policy_handle connect_handle
, domain_handle
;
2309 struct dom_sid2
*domain_sid
= NULL
;
2310 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2312 ZERO_STRUCT(connect_handle
);
2313 ZERO_STRUCT(domain_handle
);
2315 if (!r
->out
.buffer
) {
2316 return WERR_INVALID_PARAMETER
;
2319 switch (r
->in
.level
) {
2321 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2322 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2326 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2329 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
2332 werr
= WERR_INVALID_LEVEL
;
2336 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2339 if (!W_ERROR_IS_OK(werr
)) {
2343 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2344 SAMR_ACCESS_ENUM_DOMAINS
|
2345 SAMR_ACCESS_LOOKUP_DOMAIN
,
2350 if (!W_ERROR_IS_OK(werr
)) {
2357 /* 3: 12 (DomainInfo2) */
2359 status
= query_USER_MODALS_INFO_to_buffer(ctx
,
2365 if (!NT_STATUS_IS_OK(status
)) {
2366 werr
= ntstatus_to_werror(status
);
2371 if (ctx
->disable_policy_handle_cache
) {
2372 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2373 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2379 /****************************************************************
2380 ****************************************************************/
2382 WERROR
NetUserModalsGet_l(struct libnetapi_ctx
*ctx
,
2383 struct NetUserModalsGet
*r
)
2385 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsGet
);
2388 /****************************************************************
2389 ****************************************************************/
2391 static NTSTATUS
set_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2392 struct rpc_pipe_client
*pipe_cli
,
2393 struct policy_handle
*domain_handle
,
2394 struct samr_DomInfo1
*info1
,
2395 struct samr_DomInfo3
*info3
,
2396 struct samr_DomInfo12
*info12
)
2398 NTSTATUS status
, result
;
2399 union samr_DomainInfo dom_info
;
2400 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2404 ZERO_STRUCT(dom_info
);
2406 dom_info
.info1
= *info1
;
2408 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2413 NT_STATUS_NOT_OK_RETURN(status
);
2414 NT_STATUS_NOT_OK_RETURN(result
);
2419 ZERO_STRUCT(dom_info
);
2421 dom_info
.info3
= *info3
;
2423 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2429 NT_STATUS_NOT_OK_RETURN(status
);
2430 NT_STATUS_NOT_OK_RETURN(result
);
2435 ZERO_STRUCT(dom_info
);
2437 dom_info
.info12
= *info12
;
2439 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2445 NT_STATUS_NOT_OK_RETURN(status
);
2446 NT_STATUS_NOT_OK_RETURN(result
);
2449 return NT_STATUS_OK
;
2452 /****************************************************************
2453 ****************************************************************/
2455 static NTSTATUS
set_USER_MODALS_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
2456 struct rpc_pipe_client
*pipe_cli
,
2457 struct policy_handle
*domain_handle
,
2458 struct USER_MODALS_INFO_0
*info0
)
2461 struct samr_DomInfo1 dom_info_1
;
2462 struct samr_DomInfo3 dom_info_3
;
2464 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2473 NT_STATUS_NOT_OK_RETURN(status
);
2475 dom_info_1
.min_password_length
=
2476 info0
->usrmod0_min_passwd_len
;
2477 dom_info_1
.password_history_length
=
2478 info0
->usrmod0_password_hist_len
;
2480 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2481 info0
->usrmod0_max_passwd_age
);
2482 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2483 info0
->usrmod0_min_passwd_age
);
2485 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2486 info0
->usrmod0_force_logoff
);
2488 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2496 /****************************************************************
2497 ****************************************************************/
2499 static NTSTATUS
set_USER_MODALS_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
2500 struct rpc_pipe_client
*pipe_cli
,
2501 struct policy_handle
*domain_handle
,
2502 struct USER_MODALS_INFO_3
*info3
)
2505 struct samr_DomInfo12 dom_info_12
;
2507 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2516 NT_STATUS_NOT_OK_RETURN(status
);
2518 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_duration
,
2519 info3
->usrmod3_lockout_duration
);
2520 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_window
,
2521 info3
->usrmod3_lockout_observation_window
);
2522 dom_info_12
.lockout_threshold
= info3
->usrmod3_lockout_threshold
;
2524 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2532 /****************************************************************
2533 ****************************************************************/
2535 static NTSTATUS
set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX
*mem_ctx
,
2536 struct rpc_pipe_client
*pipe_cli
,
2537 struct policy_handle
*domain_handle
,
2538 struct USER_MODALS_INFO_1001
*info1001
)
2541 struct samr_DomInfo1 dom_info_1
;
2543 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2552 NT_STATUS_NOT_OK_RETURN(status
);
2554 dom_info_1
.min_password_length
=
2555 info1001
->usrmod1001_min_passwd_len
;
2557 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2565 /****************************************************************
2566 ****************************************************************/
2568 static NTSTATUS
set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX
*mem_ctx
,
2569 struct rpc_pipe_client
*pipe_cli
,
2570 struct policy_handle
*domain_handle
,
2571 struct USER_MODALS_INFO_1002
*info1002
)
2574 struct samr_DomInfo1 dom_info_1
;
2576 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2585 NT_STATUS_NOT_OK_RETURN(status
);
2587 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2588 info1002
->usrmod1002_max_passwd_age
);
2590 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2598 /****************************************************************
2599 ****************************************************************/
2601 static NTSTATUS
set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX
*mem_ctx
,
2602 struct rpc_pipe_client
*pipe_cli
,
2603 struct policy_handle
*domain_handle
,
2604 struct USER_MODALS_INFO_1003
*info1003
)
2607 struct samr_DomInfo1 dom_info_1
;
2609 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2618 NT_STATUS_NOT_OK_RETURN(status
);
2620 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2621 info1003
->usrmod1003_min_passwd_age
);
2623 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2631 /****************************************************************
2632 ****************************************************************/
2634 static NTSTATUS
set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX
*mem_ctx
,
2635 struct rpc_pipe_client
*pipe_cli
,
2636 struct policy_handle
*domain_handle
,
2637 struct USER_MODALS_INFO_1004
*info1004
)
2640 struct samr_DomInfo3 dom_info_3
;
2642 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2651 NT_STATUS_NOT_OK_RETURN(status
);
2653 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2654 info1004
->usrmod1004_force_logoff
);
2656 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2664 /****************************************************************
2665 ****************************************************************/
2667 static NTSTATUS
set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX
*mem_ctx
,
2668 struct rpc_pipe_client
*pipe_cli
,
2669 struct policy_handle
*domain_handle
,
2670 struct USER_MODALS_INFO_1005
*info1005
)
2673 struct samr_DomInfo1 dom_info_1
;
2675 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2684 NT_STATUS_NOT_OK_RETURN(status
);
2686 dom_info_1
.password_history_length
=
2687 info1005
->usrmod1005_password_hist_len
;
2689 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2697 /****************************************************************
2698 ****************************************************************/
2700 static NTSTATUS
set_USER_MODALS_INFO_buffer(TALLOC_CTX
*mem_ctx
,
2701 struct rpc_pipe_client
*pipe_cli
,
2703 struct policy_handle
*domain_handle
,
2704 struct dom_sid
*domain_sid
,
2707 struct USER_MODALS_INFO_0
*info0
;
2708 struct USER_MODALS_INFO_3
*info3
;
2709 struct USER_MODALS_INFO_1001
*info1001
;
2710 struct USER_MODALS_INFO_1002
*info1002
;
2711 struct USER_MODALS_INFO_1003
*info1003
;
2712 struct USER_MODALS_INFO_1004
*info1004
;
2713 struct USER_MODALS_INFO_1005
*info1005
;
2716 return ERROR_INSUFFICIENT_BUFFER
;
2721 info0
= (struct USER_MODALS_INFO_0
*)buffer
;
2722 return set_USER_MODALS_INFO_0_buffer(mem_ctx
,
2727 info3
= (struct USER_MODALS_INFO_3
*)buffer
;
2728 return set_USER_MODALS_INFO_3_buffer(mem_ctx
,
2733 info1001
= (struct USER_MODALS_INFO_1001
*)buffer
;
2734 return set_USER_MODALS_INFO_1001_buffer(mem_ctx
,
2739 info1002
= (struct USER_MODALS_INFO_1002
*)buffer
;
2740 return set_USER_MODALS_INFO_1002_buffer(mem_ctx
,
2745 info1003
= (struct USER_MODALS_INFO_1003
*)buffer
;
2746 return set_USER_MODALS_INFO_1003_buffer(mem_ctx
,
2751 info1004
= (struct USER_MODALS_INFO_1004
*)buffer
;
2752 return set_USER_MODALS_INFO_1004_buffer(mem_ctx
,
2757 info1005
= (struct USER_MODALS_INFO_1005
*)buffer
;
2758 return set_USER_MODALS_INFO_1005_buffer(mem_ctx
,
2767 return NT_STATUS_OK
;
2770 /****************************************************************
2771 ****************************************************************/
2773 WERROR
NetUserModalsSet_r(struct libnetapi_ctx
*ctx
,
2774 struct NetUserModalsSet
*r
)
2776 struct rpc_pipe_client
*pipe_cli
= NULL
;
2780 struct policy_handle connect_handle
, domain_handle
;
2781 struct dom_sid2
*domain_sid
= NULL
;
2782 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2784 ZERO_STRUCT(connect_handle
);
2785 ZERO_STRUCT(domain_handle
);
2787 if (!r
->in
.buffer
) {
2788 return WERR_INVALID_PARAMETER
;
2791 switch (r
->in
.level
) {
2793 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2794 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2795 SAMR_DOMAIN_ACCESS_SET_INFO_1
|
2796 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2803 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2804 SAMR_DOMAIN_ACCESS_SET_INFO_1
;
2807 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2808 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2814 werr
= WERR_NOT_SUPPORTED
;
2817 werr
= WERR_INVALID_LEVEL
;
2821 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2824 if (!W_ERROR_IS_OK(werr
)) {
2828 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2829 SAMR_ACCESS_ENUM_DOMAINS
|
2830 SAMR_ACCESS_LOOKUP_DOMAIN
,
2835 if (!W_ERROR_IS_OK(werr
)) {
2839 status
= set_USER_MODALS_INFO_buffer(ctx
,
2845 if (!NT_STATUS_IS_OK(status
)) {
2846 werr
= ntstatus_to_werror(status
);
2851 if (ctx
->disable_policy_handle_cache
) {
2852 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2853 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2859 /****************************************************************
2860 ****************************************************************/
2862 WERROR
NetUserModalsSet_l(struct libnetapi_ctx
*ctx
,
2863 struct NetUserModalsSet
*r
)
2865 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsSet
);
2868 /****************************************************************
2869 ****************************************************************/
2871 NTSTATUS
add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
2873 const char *group_name
,
2874 uint32_t attributes
,
2876 uint32_t *num_entries
)
2878 struct GROUP_USERS_INFO_0 u0
;
2879 struct GROUP_USERS_INFO_1 u1
;
2884 u0
.grui0_name
= talloc_strdup(mem_ctx
, group_name
);
2885 NT_STATUS_HAVE_NO_MEMORY(u0
.grui0_name
);
2887 u0
.grui0_name
= NULL
;
2890 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_0
, u0
,
2891 (struct GROUP_USERS_INFO_0
**)buffer
, num_entries
);
2895 u1
.grui1_name
= talloc_strdup(mem_ctx
, group_name
);
2896 NT_STATUS_HAVE_NO_MEMORY(u1
.grui1_name
);
2898 u1
.grui1_name
= NULL
;
2901 u1
.grui1_attributes
= attributes
;
2903 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_1
, u1
,
2904 (struct GROUP_USERS_INFO_1
**)buffer
, num_entries
);
2907 return NT_STATUS_INVALID_INFO_CLASS
;
2910 return NT_STATUS_OK
;
2913 /****************************************************************
2914 ****************************************************************/
2916 WERROR
NetUserGetGroups_r(struct libnetapi_ctx
*ctx
,
2917 struct NetUserGetGroups
*r
)
2919 struct rpc_pipe_client
*pipe_cli
= NULL
;
2920 struct policy_handle connect_handle
, domain_handle
, user_handle
;
2921 struct lsa_String lsa_account_name
;
2922 struct dom_sid2
*domain_sid
= NULL
;
2923 struct samr_Ids user_rids
, name_types
;
2924 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
2925 struct lsa_Strings names
;
2926 struct samr_Ids types
;
2927 uint32_t *rids
= NULL
;
2930 uint32_t entries_read
= 0;
2933 NTSTATUS result
= NT_STATUS_OK
;
2935 struct dcerpc_binding_handle
*b
= NULL
;
2937 ZERO_STRUCT(connect_handle
);
2938 ZERO_STRUCT(domain_handle
);
2940 if (!r
->out
.buffer
) {
2941 return WERR_INVALID_PARAMETER
;
2944 *r
->out
.buffer
= NULL
;
2945 *r
->out
.entries_read
= 0;
2946 *r
->out
.total_entries
= 0;
2948 switch (r
->in
.level
) {
2953 return WERR_INVALID_LEVEL
;
2956 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2959 if (!W_ERROR_IS_OK(werr
)) {
2963 b
= pipe_cli
->binding_handle
;
2965 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2966 SAMR_ACCESS_ENUM_DOMAINS
|
2967 SAMR_ACCESS_LOOKUP_DOMAIN
,
2968 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
2972 if (!W_ERROR_IS_OK(werr
)) {
2976 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
2978 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
2985 if (any_nt_status_not_ok(status
, result
, &status
)) {
2986 werr
= ntstatus_to_werror(status
);
2989 if (user_rids
.count
!= 1) {
2990 werr
= WERR_BAD_NET_RESP
;
2993 if (name_types
.count
!= 1) {
2994 werr
= WERR_BAD_NET_RESP
;
2998 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3000 SAMR_USER_ACCESS_GET_GROUPS
,
3004 if (any_nt_status_not_ok(status
, result
, &status
)) {
3005 werr
= ntstatus_to_werror(status
);
3009 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3013 if (any_nt_status_not_ok(status
, result
, &status
)) {
3014 werr
= ntstatus_to_werror(status
);
3018 rids
= talloc_array(ctx
, uint32_t, rid_array
->count
);
3020 werr
= WERR_NOT_ENOUGH_MEMORY
;
3024 for (i
=0; i
< rid_array
->count
; i
++) {
3025 rids
[i
] = rid_array
->rids
[i
].rid
;
3028 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3035 if (!NT_STATUS_IS_OK(status
)) {
3036 werr
= ntstatus_to_werror(status
);
3039 if (!NT_STATUS_IS_OK(result
) &&
3040 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3041 werr
= ntstatus_to_werror(result
);
3044 if (names
.count
!= rid_array
->count
) {
3045 werr
= WERR_BAD_NET_RESP
;
3048 if (types
.count
!= rid_array
->count
) {
3049 werr
= WERR_BAD_NET_RESP
;
3053 for (i
=0; i
< names
.count
; i
++) {
3054 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
3056 names
.names
[i
].string
,
3057 rid_array
->rids
[i
].attributes
,
3060 if (!NT_STATUS_IS_OK(status
)) {
3061 werr
= ntstatus_to_werror(status
);
3066 *r
->out
.entries_read
= entries_read
;
3067 *r
->out
.total_entries
= entries_read
;
3070 if (ctx
->disable_policy_handle_cache
) {
3071 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3072 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3078 /****************************************************************
3079 ****************************************************************/
3081 WERROR
NetUserGetGroups_l(struct libnetapi_ctx
*ctx
,
3082 struct NetUserGetGroups
*r
)
3084 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetGroups
);
3087 /****************************************************************
3088 ****************************************************************/
3090 WERROR
NetUserSetGroups_r(struct libnetapi_ctx
*ctx
,
3091 struct NetUserSetGroups
*r
)
3093 struct rpc_pipe_client
*pipe_cli
= NULL
;
3094 struct policy_handle connect_handle
, domain_handle
, user_handle
, group_handle
;
3095 struct lsa_String lsa_account_name
;
3096 struct dom_sid2
*domain_sid
= NULL
;
3097 struct samr_Ids user_rids
, name_types
;
3098 struct samr_Ids group_rids
;
3099 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3100 struct lsa_String
*lsa_names
= NULL
;
3102 uint32_t *add_rids
= NULL
;
3103 uint32_t *del_rids
= NULL
;
3104 size_t num_add_rids
= 0;
3105 size_t num_del_rids
= 0;
3107 uint32_t *member_rids
= NULL
;
3109 struct GROUP_USERS_INFO_0
*i0
= NULL
;
3110 struct GROUP_USERS_INFO_1
*i1
= NULL
;
3115 NTSTATUS result
= NT_STATUS_OK
;
3117 struct dcerpc_binding_handle
*b
= NULL
;
3119 ZERO_STRUCT(connect_handle
);
3120 ZERO_STRUCT(domain_handle
);
3121 ZERO_STRUCT(group_handle
);
3123 if (!r
->in
.buffer
) {
3124 return WERR_INVALID_PARAMETER
;
3127 switch (r
->in
.level
) {
3132 return WERR_INVALID_LEVEL
;
3135 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3138 if (!W_ERROR_IS_OK(werr
)) {
3142 b
= pipe_cli
->binding_handle
;
3144 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3145 SAMR_ACCESS_ENUM_DOMAINS
|
3146 SAMR_ACCESS_LOOKUP_DOMAIN
,
3147 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3151 if (!W_ERROR_IS_OK(werr
)) {
3155 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3157 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3164 if (any_nt_status_not_ok(status
, result
, &status
)) {
3165 werr
= ntstatus_to_werror(status
);
3168 if (user_rids
.count
!= 1) {
3169 werr
= WERR_BAD_NET_RESP
;
3172 if (name_types
.count
!= 1) {
3173 werr
= WERR_BAD_NET_RESP
;
3177 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3179 SAMR_USER_ACCESS_GET_GROUPS
,
3183 if (any_nt_status_not_ok(status
, result
, &status
)) {
3184 werr
= ntstatus_to_werror(status
);
3188 switch (r
->in
.level
) {
3190 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
3193 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
3197 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
3199 werr
= WERR_NOT_ENOUGH_MEMORY
;
3203 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3205 switch (r
->in
.level
) {
3207 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
3211 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
3217 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3224 if (any_nt_status_not_ok(status
, result
, &status
)) {
3225 werr
= ntstatus_to_werror(status
);
3228 if (group_rids
.count
!= r
->in
.num_entries
) {
3229 werr
= WERR_BAD_NET_RESP
;
3232 if (name_types
.count
!= r
->in
.num_entries
) {
3233 werr
= WERR_BAD_NET_RESP
;
3237 member_rids
= group_rids
.ids
;
3239 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3243 if (any_nt_status_not_ok(status
, result
, &status
)) {
3244 werr
= ntstatus_to_werror(status
);
3250 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3251 bool already_member
= false;
3252 for (k
=0; k
< rid_array
->count
; k
++) {
3253 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3254 already_member
= true;
3258 if (!already_member
) {
3259 if (!add_rid_to_array_unique(ctx
,
3261 &add_rids
, &num_add_rids
)) {
3262 werr
= WERR_GEN_FAILURE
;
3270 for (k
=0; k
< rid_array
->count
; k
++) {
3271 bool keep_member
= false;
3272 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3273 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3279 if (!add_rid_to_array_unique(ctx
,
3280 rid_array
->rids
[k
].rid
,
3281 &del_rids
, &num_del_rids
)) {
3282 werr
= WERR_GEN_FAILURE
;
3290 for (i
=0; i
< num_add_rids
; i
++) {
3291 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3293 SAMR_GROUP_ACCESS_ADD_MEMBER
,
3297 if (any_nt_status_not_ok(status
, result
, &status
)) {
3298 werr
= ntstatus_to_werror(status
);
3302 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
3307 if (any_nt_status_not_ok(status
, result
, &status
)) {
3308 werr
= ntstatus_to_werror(status
);
3312 if (is_valid_policy_hnd(&group_handle
)) {
3313 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3319 for (i
=0; i
< num_del_rids
; i
++) {
3320 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3322 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
3326 if (any_nt_status_not_ok(status
, result
, &status
)) {
3327 werr
= ntstatus_to_werror(status
);
3331 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
3335 if (any_nt_status_not_ok(status
, result
, &status
)) {
3336 werr
= ntstatus_to_werror(status
);
3340 if (is_valid_policy_hnd(&group_handle
)) {
3341 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3348 if (is_valid_policy_hnd(&group_handle
)) {
3349 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3352 if (ctx
->disable_policy_handle_cache
) {
3353 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3354 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3360 /****************************************************************
3361 ****************************************************************/
3363 WERROR
NetUserSetGroups_l(struct libnetapi_ctx
*ctx
,
3364 struct NetUserSetGroups
*r
)
3366 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetGroups
);
3369 /****************************************************************
3370 ****************************************************************/
3372 static NTSTATUS
add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
3374 const char *group_name
,
3376 uint32_t *num_entries
)
3378 struct LOCALGROUP_USERS_INFO_0 u0
;
3382 u0
.lgrui0_name
= talloc_strdup(mem_ctx
, group_name
);
3383 NT_STATUS_HAVE_NO_MEMORY(u0
.lgrui0_name
);
3385 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_USERS_INFO_0
, u0
,
3386 (struct LOCALGROUP_USERS_INFO_0
**)buffer
, num_entries
);
3389 return NT_STATUS_INVALID_INFO_CLASS
;
3392 return NT_STATUS_OK
;
3395 /****************************************************************
3396 ****************************************************************/
3398 WERROR
NetUserGetLocalGroups_r(struct libnetapi_ctx
*ctx
,
3399 struct NetUserGetLocalGroups
*r
)
3401 struct rpc_pipe_client
*pipe_cli
= NULL
;
3402 struct policy_handle connect_handle
, domain_handle
, user_handle
,
3404 struct lsa_String lsa_account_name
;
3405 struct dom_sid2
*domain_sid
= NULL
;
3406 struct samr_Ids user_rids
, name_types
;
3407 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3408 struct lsa_Strings names
;
3409 struct samr_Ids types
;
3410 uint32_t *rids
= NULL
;
3411 size_t num_rids
= 0;
3412 struct dom_sid user_sid
;
3413 struct lsa_SidArray sid_array
;
3414 struct samr_Ids domain_rids
;
3415 struct samr_Ids builtin_rids
;
3418 uint32_t entries_read
= 0;
3421 NTSTATUS result
= NT_STATUS_OK
;
3423 struct dcerpc_binding_handle
*b
= NULL
;
3425 ZERO_STRUCT(connect_handle
);
3426 ZERO_STRUCT(domain_handle
);
3428 if (!r
->out
.buffer
) {
3429 return WERR_INVALID_PARAMETER
;
3432 *r
->out
.buffer
= NULL
;
3433 *r
->out
.entries_read
= 0;
3434 *r
->out
.total_entries
= 0;
3436 switch (r
->in
.level
) {
3441 return WERR_INVALID_LEVEL
;
3444 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3447 if (!W_ERROR_IS_OK(werr
)) {
3451 b
= pipe_cli
->binding_handle
;
3453 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3454 SAMR_ACCESS_ENUM_DOMAINS
|
3455 SAMR_ACCESS_LOOKUP_DOMAIN
,
3456 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3457 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3461 if (!W_ERROR_IS_OK(werr
)) {
3465 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
3466 SAMR_ACCESS_ENUM_DOMAINS
|
3467 SAMR_ACCESS_LOOKUP_DOMAIN
,
3468 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3469 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3472 if (!W_ERROR_IS_OK(werr
)) {
3476 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3478 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3485 if (any_nt_status_not_ok(status
, result
, &status
)) {
3486 werr
= ntstatus_to_werror(status
);
3489 if (user_rids
.count
!= 1) {
3490 werr
= WERR_BAD_NET_RESP
;
3493 if (name_types
.count
!= 1) {
3494 werr
= WERR_BAD_NET_RESP
;
3498 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3500 SAMR_USER_ACCESS_GET_GROUPS
,
3504 if (any_nt_status_not_ok(status
, result
, &status
)) {
3505 werr
= ntstatus_to_werror(status
);
3509 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3513 if (any_nt_status_not_ok(status
, result
, &status
)) {
3514 werr
= ntstatus_to_werror(status
);
3518 if (!sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0])) {
3519 werr
= WERR_NOT_ENOUGH_MEMORY
;
3523 sid_array
.num_sids
= rid_array
->count
+ 1;
3524 sid_array
.sids
= talloc_array(ctx
, struct lsa_SidPtr
, sid_array
.num_sids
);
3525 if (!sid_array
.sids
) {
3526 werr
= WERR_NOT_ENOUGH_MEMORY
;
3530 sid_array
.sids
[0].sid
= dom_sid_dup(ctx
, &user_sid
);
3531 if (!sid_array
.sids
[0].sid
) {
3532 werr
= WERR_NOT_ENOUGH_MEMORY
;
3536 for (i
=0; i
< rid_array
->count
; i
++) {
3539 if (!sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
)) {
3540 werr
= WERR_NOT_ENOUGH_MEMORY
;
3544 sid_array
.sids
[i
+1].sid
= dom_sid_dup(ctx
, &sid
);
3545 if (!sid_array
.sids
[i
+1].sid
) {
3546 werr
= WERR_NOT_ENOUGH_MEMORY
;
3551 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3556 if (any_nt_status_not_ok(status
, result
, &status
)) {
3557 werr
= ntstatus_to_werror(status
);
3561 for (i
=0; i
< domain_rids
.count
; i
++) {
3562 if (!add_rid_to_array_unique(ctx
, domain_rids
.ids
[i
],
3563 &rids
, &num_rids
)) {
3564 werr
= WERR_NOT_ENOUGH_MEMORY
;
3569 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3574 if (any_nt_status_not_ok(status
, result
, &status
)) {
3575 werr
= ntstatus_to_werror(status
);
3579 for (i
=0; i
< builtin_rids
.count
; i
++) {
3580 if (!add_rid_to_array_unique(ctx
, builtin_rids
.ids
[i
],
3581 &rids
, &num_rids
)) {
3582 werr
= WERR_NOT_ENOUGH_MEMORY
;
3587 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3594 if (any_nt_status_not_ok(status
, result
, &status
)) {
3595 werr
= ntstatus_to_werror(status
);
3598 if (names
.count
!= num_rids
) {
3599 werr
= WERR_BAD_NET_RESP
;
3602 if (types
.count
!= num_rids
) {
3603 werr
= WERR_BAD_NET_RESP
;
3607 for (i
=0; i
< names
.count
; i
++) {
3608 status
= add_LOCALGROUP_USERS_INFO_X_buffer(ctx
,
3610 names
.names
[i
].string
,
3613 if (!NT_STATUS_IS_OK(status
)) {
3614 werr
= ntstatus_to_werror(status
);
3619 *r
->out
.entries_read
= entries_read
;
3620 *r
->out
.total_entries
= entries_read
;
3623 if (ctx
->disable_policy_handle_cache
) {
3624 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3625 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3631 /****************************************************************
3632 ****************************************************************/
3634 WERROR
NetUserGetLocalGroups_l(struct libnetapi_ctx
*ctx
,
3635 struct NetUserGetLocalGroups
*r
)
3637 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetLocalGroups
);