2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "../librpc/gen_ndr/ndr_samr_c.h"
27 #include "rpc_client/init_samr.h"
28 #include "../libds/common/flags.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../libds/common/flag_mapping.h"
32 #include "rpc_client/cli_pipe.h"
34 /****************************************************************
35 ****************************************************************/
37 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X
*infoX
,
38 struct samr_UserInfo21
*info21
)
40 uint32_t fields_present
= 0;
41 struct samr_LogonHours zero_logon_hours
;
42 struct lsa_BinaryString zero_parameters
;
46 ZERO_STRUCT(zero_logon_hours
);
47 ZERO_STRUCT(zero_parameters
);
49 if (infoX
->usriX_flags
) {
50 fields_present
|= SAMR_FIELD_ACCT_FLAGS
;
52 if (infoX
->usriX_name
) {
53 fields_present
|= SAMR_FIELD_ACCOUNT_NAME
;
55 if (infoX
->usriX_password
) {
56 fields_present
|= SAMR_FIELD_NT_PASSWORD_PRESENT
;
58 if (infoX
->usriX_flags
) {
59 fields_present
|= SAMR_FIELD_ACCT_FLAGS
;
61 if (infoX
->usriX_home_dir
) {
62 fields_present
|= SAMR_FIELD_HOME_DIRECTORY
;
64 if (infoX
->usriX_script_path
) {
65 fields_present
|= SAMR_FIELD_LOGON_SCRIPT
;
67 if (infoX
->usriX_comment
) {
68 fields_present
|= SAMR_FIELD_DESCRIPTION
;
70 if (infoX
->usriX_password_age
) {
71 fields_present
|= SAMR_FIELD_FORCE_PWD_CHANGE
;
73 if (infoX
->usriX_full_name
) {
74 fields_present
|= SAMR_FIELD_FULL_NAME
;
76 if (infoX
->usriX_usr_comment
) {
77 fields_present
|= SAMR_FIELD_COMMENT
;
79 if (infoX
->usriX_profile
) {
80 fields_present
|= SAMR_FIELD_PROFILE_PATH
;
82 if (infoX
->usriX_home_dir_drive
) {
83 fields_present
|= SAMR_FIELD_HOME_DRIVE
;
85 if (infoX
->usriX_primary_group_id
) {
86 fields_present
|= SAMR_FIELD_PRIMARY_GID
;
88 if (infoX
->usriX_country_code
) {
89 fields_present
|= SAMR_FIELD_COUNTRY_CODE
;
91 if (infoX
->usriX_workstations
) {
92 fields_present
|= SAMR_FIELD_WORKSTATIONS
;
95 unix_to_nt_time_abs(&password_age
, infoX
->usriX_password_age
);
97 /* TODO: infoX->usriX_priv */
99 info21
->last_logon
= 0;
100 info21
->last_logoff
= 0;
101 info21
->last_password_change
= 0;
102 info21
->acct_expiry
= 0;
103 info21
->allow_password_change
= 0;
104 info21
->force_password_change
= 0;
105 info21
->account_name
.string
= infoX
->usriX_name
;
106 info21
->full_name
.string
= infoX
->usriX_full_name
;
107 info21
->home_directory
.string
= infoX
->usriX_home_dir
;
108 info21
->home_drive
.string
= infoX
->usriX_home_dir_drive
;
109 info21
->logon_script
.string
= infoX
->usriX_script_path
;
110 info21
->profile_path
.string
= infoX
->usriX_profile
;
111 info21
->description
.string
= infoX
->usriX_comment
;
112 info21
->workstations
.string
= infoX
->usriX_workstations
;
113 info21
->comment
.string
= infoX
->usriX_usr_comment
;
114 info21
->parameters
= zero_parameters
;
115 info21
->lm_owf_password
= zero_parameters
;
116 info21
->nt_owf_password
= zero_parameters
;
117 info21
->private_data
.string
= NULL
;
118 info21
->buf_count
= 0;
119 info21
->buffer
= NULL
;
120 info21
->rid
= infoX
->usriX_user_id
;
121 info21
->primary_gid
= infoX
->usriX_primary_group_id
;
122 info21
->acct_flags
= infoX
->usriX_flags
;
123 info21
->fields_present
= fields_present
;
124 info21
->logon_hours
= zero_logon_hours
;
125 info21
->bad_password_count
= infoX
->usriX_bad_pw_count
;
126 info21
->logon_count
= infoX
->usriX_num_logons
;
127 info21
->country_code
= infoX
->usriX_country_code
;
128 info21
->code_page
= infoX
->usriX_code_page
;
129 info21
->lm_password_set
= 0;
130 info21
->nt_password_set
= 0;
131 info21
->password_expired
= infoX
->usriX_password_expired
;
132 info21
->private_data_sensitive
= 0;
135 /****************************************************************
136 ****************************************************************/
138 static NTSTATUS
construct_USER_INFO_X(uint32_t level
,
140 struct USER_INFO_X
*uX
)
142 struct USER_INFO_0
*u0
= NULL
;
143 struct USER_INFO_1
*u1
= NULL
;
144 struct USER_INFO_2
*u2
= NULL
;
145 struct USER_INFO_3
*u3
= NULL
;
146 struct USER_INFO_1003
*u1003
= NULL
;
147 struct USER_INFO_1006
*u1006
= NULL
;
148 struct USER_INFO_1007
*u1007
= NULL
;
149 struct USER_INFO_1009
*u1009
= NULL
;
150 struct USER_INFO_1011
*u1011
= NULL
;
151 struct USER_INFO_1012
*u1012
= NULL
;
152 struct USER_INFO_1014
*u1014
= NULL
;
153 struct USER_INFO_1024
*u1024
= NULL
;
154 struct USER_INFO_1051
*u1051
= NULL
;
155 struct USER_INFO_1052
*u1052
= NULL
;
156 struct USER_INFO_1053
*u1053
= NULL
;
158 if (!buffer
|| !uX
) {
159 return NT_STATUS_INVALID_PARAMETER
;
166 u0
= (struct USER_INFO_0
*)buffer
;
167 uX
->usriX_name
= u0
->usri0_name
;
170 u1
= (struct USER_INFO_1
*)buffer
;
171 uX
->usriX_name
= u1
->usri1_name
;
172 uX
->usriX_password
= u1
->usri1_password
;
173 uX
->usriX_password_age
= u1
->usri1_password_age
;
174 uX
->usriX_priv
= u1
->usri1_priv
;
175 uX
->usriX_home_dir
= u1
->usri1_home_dir
;
176 uX
->usriX_comment
= u1
->usri1_comment
;
177 uX
->usriX_flags
= u1
->usri1_flags
;
178 uX
->usriX_script_path
= u1
->usri1_script_path
;
181 u2
= (struct USER_INFO_2
*)buffer
;
182 uX
->usriX_name
= u2
->usri2_name
;
183 uX
->usriX_password
= u2
->usri2_password
;
184 uX
->usriX_password_age
= u2
->usri2_password_age
;
185 uX
->usriX_priv
= u2
->usri2_priv
;
186 uX
->usriX_home_dir
= u2
->usri2_home_dir
;
187 uX
->usriX_comment
= u2
->usri2_comment
;
188 uX
->usriX_flags
= u2
->usri2_flags
;
189 uX
->usriX_script_path
= u2
->usri2_script_path
;
190 uX
->usriX_auth_flags
= u2
->usri2_auth_flags
;
191 uX
->usriX_full_name
= u2
->usri2_full_name
;
192 uX
->usriX_usr_comment
= u2
->usri2_usr_comment
;
193 uX
->usriX_parms
= u2
->usri2_parms
;
194 uX
->usriX_workstations
= u2
->usri2_workstations
;
195 uX
->usriX_last_logon
= u2
->usri2_last_logon
;
196 uX
->usriX_last_logoff
= u2
->usri2_last_logoff
;
197 uX
->usriX_acct_expires
= u2
->usri2_acct_expires
;
198 uX
->usriX_max_storage
= u2
->usri2_max_storage
;
199 uX
->usriX_units_per_week
= u2
->usri2_units_per_week
;
200 uX
->usriX_logon_hours
= u2
->usri2_logon_hours
;
201 uX
->usriX_bad_pw_count
= u2
->usri2_bad_pw_count
;
202 uX
->usriX_num_logons
= u2
->usri2_num_logons
;
203 uX
->usriX_logon_server
= u2
->usri2_logon_server
;
204 uX
->usriX_country_code
= u2
->usri2_country_code
;
205 uX
->usriX_code_page
= u2
->usri2_code_page
;
208 u3
= (struct USER_INFO_3
*)buffer
;
209 uX
->usriX_name
= u3
->usri3_name
;
210 uX
->usriX_password_age
= u3
->usri3_password_age
;
211 uX
->usriX_priv
= u3
->usri3_priv
;
212 uX
->usriX_home_dir
= u3
->usri3_home_dir
;
213 uX
->usriX_comment
= u3
->usri3_comment
;
214 uX
->usriX_flags
= u3
->usri3_flags
;
215 uX
->usriX_script_path
= u3
->usri3_script_path
;
216 uX
->usriX_auth_flags
= u3
->usri3_auth_flags
;
217 uX
->usriX_full_name
= u3
->usri3_full_name
;
218 uX
->usriX_usr_comment
= u3
->usri3_usr_comment
;
219 uX
->usriX_parms
= u3
->usri3_parms
;
220 uX
->usriX_workstations
= u3
->usri3_workstations
;
221 uX
->usriX_last_logon
= u3
->usri3_last_logon
;
222 uX
->usriX_last_logoff
= u3
->usri3_last_logoff
;
223 uX
->usriX_acct_expires
= u3
->usri3_acct_expires
;
224 uX
->usriX_max_storage
= u3
->usri3_max_storage
;
225 uX
->usriX_units_per_week
= u3
->usri3_units_per_week
;
226 uX
->usriX_logon_hours
= u3
->usri3_logon_hours
;
227 uX
->usriX_bad_pw_count
= u3
->usri3_bad_pw_count
;
228 uX
->usriX_num_logons
= u3
->usri3_num_logons
;
229 uX
->usriX_logon_server
= u3
->usri3_logon_server
;
230 uX
->usriX_country_code
= u3
->usri3_country_code
;
231 uX
->usriX_code_page
= u3
->usri3_code_page
;
232 uX
->usriX_user_id
= u3
->usri3_user_id
;
233 uX
->usriX_primary_group_id
= u3
->usri3_primary_group_id
;
234 uX
->usriX_profile
= u3
->usri3_profile
;
235 uX
->usriX_home_dir_drive
= u3
->usri3_home_dir_drive
;
236 uX
->usriX_password_expired
= u3
->usri3_password_expired
;
239 u1003
= (struct USER_INFO_1003
*)buffer
;
240 uX
->usriX_password
= u1003
->usri1003_password
;
243 u1006
= (struct USER_INFO_1006
*)buffer
;
244 uX
->usriX_home_dir
= u1006
->usri1006_home_dir
;
247 u1007
= (struct USER_INFO_1007
*)buffer
;
248 uX
->usriX_comment
= u1007
->usri1007_comment
;
251 u1009
= (struct USER_INFO_1009
*)buffer
;
252 uX
->usriX_script_path
= u1009
->usri1009_script_path
;
255 u1011
= (struct USER_INFO_1011
*)buffer
;
256 uX
->usriX_full_name
= u1011
->usri1011_full_name
;
259 u1012
= (struct USER_INFO_1012
*)buffer
;
260 uX
->usriX_usr_comment
= u1012
->usri1012_usr_comment
;
263 u1014
= (struct USER_INFO_1014
*)buffer
;
264 uX
->usriX_workstations
= u1014
->usri1014_workstations
;
267 u1024
= (struct USER_INFO_1024
*)buffer
;
268 uX
->usriX_country_code
= u1024
->usri1024_country_code
;
271 u1051
= (struct USER_INFO_1051
*)buffer
;
272 uX
->usriX_primary_group_id
= u1051
->usri1051_primary_group_id
;
275 u1052
= (struct USER_INFO_1052
*)buffer
;
276 uX
->usriX_profile
= u1052
->usri1052_profile
;
279 u1053
= (struct USER_INFO_1053
*)buffer
;
280 uX
->usriX_home_dir_drive
= u1053
->usri1053_home_dir_drive
;
284 return NT_STATUS_INVALID_INFO_CLASS
;
290 /****************************************************************
291 ****************************************************************/
293 static NTSTATUS
set_user_info_USER_INFO_X(TALLOC_CTX
*ctx
,
294 struct rpc_pipe_client
*pipe_cli
,
295 DATA_BLOB
*session_key
,
296 struct policy_handle
*user_handle
,
297 struct USER_INFO_X
*uX
)
299 union samr_UserInfo user_info
;
300 struct samr_UserInfo21 info21
;
301 NTSTATUS status
, result
;
302 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
305 return NT_STATUS_INVALID_PARAMETER
;
308 convert_USER_INFO_X_to_samr_user_info21(uX
, &info21
);
310 ZERO_STRUCT(user_info
);
312 if (uX
->usriX_password
) {
314 user_info
.info25
.info
= info21
;
316 init_samr_CryptPasswordEx(uX
->usriX_password
,
318 &user_info
.info25
.password
);
320 status
= dcerpc_samr_SetUserInfo2(b
, talloc_tos(),
325 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
)) {
327 user_info
.info23
.info
= info21
;
329 init_samr_CryptPassword(uX
->usriX_password
,
331 &user_info
.info23
.password
);
333 status
= dcerpc_samr_SetUserInfo2(b
, talloc_tos(),
338 if (!NT_STATUS_IS_OK(status
)) {
343 if (!NT_STATUS_IS_OK(status
)) {
348 user_info
.info21
= info21
;
350 status
= dcerpc_samr_SetUserInfo(b
, talloc_tos(),
355 if (!NT_STATUS_IS_OK(status
)) {
363 /****************************************************************
364 ****************************************************************/
366 WERROR
NetUserAdd_r(struct libnetapi_ctx
*ctx
,
367 struct NetUserAdd
*r
)
369 struct rpc_pipe_client
*pipe_cli
= NULL
;
370 NTSTATUS status
, result
;
372 struct policy_handle connect_handle
, domain_handle
, user_handle
;
373 struct lsa_String lsa_account_name
;
374 struct dom_sid2
*domain_sid
= NULL
;
375 union samr_UserInfo
*user_info
= NULL
;
376 struct samr_PwInfo pw_info
;
377 uint32_t access_granted
= 0;
379 struct USER_INFO_X uX
;
380 struct dcerpc_binding_handle
*b
= NULL
;
381 DATA_BLOB session_key
;
383 ZERO_STRUCT(connect_handle
);
384 ZERO_STRUCT(domain_handle
);
385 ZERO_STRUCT(user_handle
);
388 return WERR_INVALID_PARAM
;
391 switch (r
->in
.level
) {
398 werr
= WERR_NOT_SUPPORTED
;
402 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
403 &ndr_table_samr
.syntax_id
,
405 if (!W_ERROR_IS_OK(werr
)) {
409 b
= pipe_cli
->binding_handle
;
411 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
412 if (!NT_STATUS_IS_OK(status
)) {
413 werr
= ntstatus_to_werror(status
);
417 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
418 SAMR_ACCESS_ENUM_DOMAINS
|
419 SAMR_ACCESS_LOOKUP_DOMAIN
,
420 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
421 SAMR_DOMAIN_ACCESS_CREATE_USER
|
422 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
426 if (!W_ERROR_IS_OK(werr
)) {
430 init_lsa_String(&lsa_account_name
, uX
.usriX_name
);
432 status
= dcerpc_samr_CreateUser2(b
, talloc_tos(),
438 SAMR_USER_ACCESS_SET_PASSWORD
|
439 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
440 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
445 if (!NT_STATUS_IS_OK(status
)) {
446 werr
= ntstatus_to_werror(status
);
449 if (!NT_STATUS_IS_OK(result
)) {
450 werr
= ntstatus_to_werror(result
);
454 status
= dcerpc_samr_QueryUserInfo(b
, talloc_tos(),
459 if (!NT_STATUS_IS_OK(status
)) {
460 werr
= ntstatus_to_werror(status
);
463 if (!NT_STATUS_IS_OK(result
)) {
464 werr
= ntstatus_to_werror(result
);
468 if (!(user_info
->info16
.acct_flags
& ACB_NORMAL
)) {
469 werr
= WERR_INVALID_PARAM
;
473 status
= dcerpc_samr_GetUserPwInfo(b
, talloc_tos(),
477 if (!NT_STATUS_IS_OK(status
)) {
478 werr
= ntstatus_to_werror(status
);
481 if (!NT_STATUS_IS_OK(result
)) {
482 werr
= ntstatus_to_werror(result
);
486 status
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
487 if (!NT_STATUS_IS_OK(status
)) {
488 werr
= ntstatus_to_werror(status
);
492 uX
.usriX_flags
|= ACB_NORMAL
;
494 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
498 if (!NT_STATUS_IS_OK(status
)) {
499 werr
= ntstatus_to_werror(status
);
507 dcerpc_samr_DeleteUser(b
, talloc_tos(),
512 if (is_valid_policy_hnd(&user_handle
) && b
) {
513 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
516 if (ctx
->disable_policy_handle_cache
) {
517 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
518 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
524 /****************************************************************
525 ****************************************************************/
527 WERROR
NetUserAdd_l(struct libnetapi_ctx
*ctx
,
528 struct NetUserAdd
*r
)
530 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserAdd
);
533 /****************************************************************
534 ****************************************************************/
536 WERROR
NetUserDel_r(struct libnetapi_ctx
*ctx
,
537 struct NetUserDel
*r
)
539 struct rpc_pipe_client
*pipe_cli
= NULL
;
540 NTSTATUS status
, result
;
542 struct policy_handle connect_handle
, builtin_handle
, domain_handle
, user_handle
;
543 struct lsa_String lsa_account_name
;
544 struct samr_Ids user_rids
, name_types
;
545 struct dom_sid2
*domain_sid
= NULL
;
546 struct dom_sid2 user_sid
;
547 struct dcerpc_binding_handle
*b
= NULL
;
549 ZERO_STRUCT(connect_handle
);
550 ZERO_STRUCT(builtin_handle
);
551 ZERO_STRUCT(domain_handle
);
552 ZERO_STRUCT(user_handle
);
554 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
555 &ndr_table_samr
.syntax_id
,
558 if (!W_ERROR_IS_OK(werr
)) {
562 b
= pipe_cli
->binding_handle
;
564 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
565 SAMR_ACCESS_ENUM_DOMAINS
|
566 SAMR_ACCESS_LOOKUP_DOMAIN
,
567 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
571 if (!W_ERROR_IS_OK(werr
)) {
575 status
= dcerpc_samr_OpenDomain(b
, talloc_tos(),
577 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
578 CONST_DISCARD(struct dom_sid
*, &global_sid_Builtin
),
581 if (!NT_STATUS_IS_OK(status
)) {
582 werr
= ntstatus_to_werror(status
);
585 if (!NT_STATUS_IS_OK(result
)) {
586 werr
= ntstatus_to_werror(result
);
590 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
592 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
599 if (!NT_STATUS_IS_OK(status
)) {
600 werr
= ntstatus_to_werror(status
);
603 if (!NT_STATUS_IS_OK(result
)) {
604 werr
= ntstatus_to_werror(result
);
607 if (user_rids
.count
!= 1) {
608 werr
= WERR_BAD_NET_RESP
;
611 if (name_types
.count
!= 1) {
612 werr
= WERR_BAD_NET_RESP
;
616 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
622 if (!NT_STATUS_IS_OK(status
)) {
623 werr
= ntstatus_to_werror(status
);
626 if (!NT_STATUS_IS_OK(result
)) {
627 werr
= ntstatus_to_werror(result
);
631 sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0]);
633 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, talloc_tos(),
637 if (!NT_STATUS_IS_OK(status
)) {
638 werr
= ntstatus_to_werror(status
);
641 if (!NT_STATUS_IS_OK(result
)) {
642 werr
= ntstatus_to_werror(result
);
646 status
= dcerpc_samr_DeleteUser(b
, talloc_tos(),
649 if (!NT_STATUS_IS_OK(status
)) {
650 werr
= ntstatus_to_werror(status
);
653 if (!NT_STATUS_IS_OK(result
)) {
654 werr
= ntstatus_to_werror(result
);
661 if (is_valid_policy_hnd(&user_handle
)) {
662 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
665 if (ctx
->disable_policy_handle_cache
) {
666 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
667 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
668 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
674 /****************************************************************
675 ****************************************************************/
677 WERROR
NetUserDel_l(struct libnetapi_ctx
*ctx
,
678 struct NetUserDel
*r
)
680 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserDel
);
683 /****************************************************************
684 ****************************************************************/
686 static NTSTATUS
libnetapi_samr_lookup_user(TALLOC_CTX
*mem_ctx
,
687 struct rpc_pipe_client
*pipe_cli
,
688 struct policy_handle
*domain_handle
,
689 struct policy_handle
*builtin_handle
,
690 const char *user_name
,
691 const struct dom_sid
*domain_sid
,
694 struct samr_UserInfo21
**info21
,
695 struct sec_desc_buf
**sec_desc
,
696 uint32_t *auth_flag_p
)
698 NTSTATUS status
, result
;
700 struct policy_handle user_handle
;
701 union samr_UserInfo
*user_info
= NULL
;
702 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
703 uint32_t access_mask
= SEC_STD_READ_CONTROL
|
704 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
705 SAMR_USER_ACCESS_GET_NAME_ETC
;
706 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
708 ZERO_STRUCT(user_handle
);
714 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
715 SAMR_USER_ACCESS_GET_GROUPS
;
721 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
722 SAMR_USER_ACCESS_GET_GROUPS
|
723 SAMR_USER_ACCESS_GET_LOCALE
;
730 return NT_STATUS_INVALID_LEVEL
;
737 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
743 if (!NT_STATUS_IS_OK(status
)) {
746 if (!NT_STATUS_IS_OK(result
)) {
751 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
756 if (!NT_STATUS_IS_OK(status
)) {
759 if (!NT_STATUS_IS_OK(result
)) {
764 status
= dcerpc_samr_QuerySecurity(b
, mem_ctx
,
769 if (!NT_STATUS_IS_OK(status
)) {
772 if (!NT_STATUS_IS_OK(result
)) {
777 if (access_mask
& SAMR_USER_ACCESS_GET_GROUPS
) {
779 struct lsa_SidArray sid_array
;
780 struct samr_Ids alias_rids
;
782 uint32_t auth_flag
= 0;
785 status
= dcerpc_samr_GetGroupsForUser(b
, mem_ctx
,
789 if (!NT_STATUS_IS_OK(status
)) {
792 if (!NT_STATUS_IS_OK(result
)) {
797 sid_array
.num_sids
= rid_array
->count
+ 1;
798 sid_array
.sids
= talloc_array(mem_ctx
, struct lsa_SidPtr
,
800 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
);
802 for (i
=0; i
<rid_array
->count
; i
++) {
803 sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
);
804 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
805 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
808 sid_compose(&sid
, domain_sid
, rid
);
809 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
810 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
812 status
= dcerpc_samr_GetAliasMembership(b
, mem_ctx
,
817 if (!NT_STATUS_IS_OK(status
)) {
820 if (!NT_STATUS_IS_OK(result
)) {
825 for (i
=0; i
<alias_rids
.count
; i
++) {
826 switch (alias_rids
.ids
[i
]) {
827 case 550: /* Print Operators */
828 auth_flag
|= AF_OP_PRINT
;
830 case 549: /* Server Operators */
831 auth_flag
|= AF_OP_SERVER
;
833 case 548: /* Account Operators */
834 auth_flag
|= AF_OP_ACCOUNTS
;
842 *auth_flag_p
= auth_flag
;
846 *info21
= &user_info
->info21
;
849 if (is_valid_policy_hnd(&user_handle
)) {
850 dcerpc_samr_Close(b
, mem_ctx
, &user_handle
, &result
);
856 /****************************************************************
857 ****************************************************************/
859 static uint32_t samr_rid_to_priv_level(uint32_t rid
)
862 case DOMAIN_RID_ADMINISTRATOR
:
863 return USER_PRIV_ADMIN
;
864 case DOMAIN_RID_GUEST
:
865 return USER_PRIV_GUEST
;
867 return USER_PRIV_USER
;
871 /****************************************************************
872 ****************************************************************/
874 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb
)
876 uint32_t fl
= UF_SCRIPT
; /* god knows why */
878 fl
|= ds_acb2uf(acb
);
883 /****************************************************************
884 ****************************************************************/
886 static NTSTATUS
info21_to_USER_INFO_1(TALLOC_CTX
*mem_ctx
,
887 const struct samr_UserInfo21
*i21
,
888 struct USER_INFO_1
*i
)
891 i
->usri1_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
892 NT_STATUS_HAVE_NO_MEMORY(i
->usri1_name
);
893 i
->usri1_password
= NULL
;
894 i
->usri1_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
895 i
->usri1_priv
= samr_rid_to_priv_level(i21
->rid
);
896 i
->usri1_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
897 i
->usri1_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
898 i
->usri1_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
899 i
->usri1_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
904 /****************************************************************
905 ****************************************************************/
907 static NTSTATUS
info21_to_USER_INFO_2(TALLOC_CTX
*mem_ctx
,
908 const struct samr_UserInfo21
*i21
,
910 struct USER_INFO_2
*i
)
914 i
->usri2_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
915 NT_STATUS_HAVE_NO_MEMORY(i
->usri2_name
);
916 i
->usri2_password
= NULL
;
917 i
->usri2_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
918 i
->usri2_priv
= samr_rid_to_priv_level(i21
->rid
);
919 i
->usri2_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
920 i
->usri2_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
921 i
->usri2_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
922 i
->usri2_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
923 i
->usri2_auth_flags
= auth_flag
;
924 i
->usri2_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
925 i
->usri2_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
926 i
->usri2_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
927 i
->usri2_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
928 i
->usri2_last_logon
= nt_time_to_unix(i21
->last_logon
);
929 i
->usri2_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
930 i
->usri2_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
931 i
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
932 i
->usri2_units_per_week
= i21
->logon_hours
.units_per_week
;
933 i
->usri2_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
934 i
->usri2_bad_pw_count
= i21
->bad_password_count
;
935 i
->usri2_num_logons
= i21
->logon_count
;
936 i
->usri2_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
937 i
->usri2_country_code
= i21
->country_code
;
938 i
->usri2_code_page
= i21
->code_page
;
943 /****************************************************************
944 ****************************************************************/
946 static NTSTATUS
info21_to_USER_INFO_3(TALLOC_CTX
*mem_ctx
,
947 const struct samr_UserInfo21
*i21
,
949 struct USER_INFO_3
*i
)
953 i
->usri3_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
954 NT_STATUS_HAVE_NO_MEMORY(i
->usri3_name
);
955 i
->usri3_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
956 i
->usri3_priv
= samr_rid_to_priv_level(i21
->rid
);
957 i
->usri3_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
958 i
->usri3_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
959 i
->usri3_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
960 i
->usri3_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
961 i
->usri3_auth_flags
= auth_flag
;
962 i
->usri3_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
963 i
->usri3_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
964 i
->usri3_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
965 i
->usri3_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
966 i
->usri3_last_logon
= nt_time_to_unix(i21
->last_logon
);
967 i
->usri3_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
968 i
->usri3_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
969 i
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
970 i
->usri3_units_per_week
= i21
->logon_hours
.units_per_week
;
971 i
->usri3_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
972 i
->usri3_bad_pw_count
= i21
->bad_password_count
;
973 i
->usri3_num_logons
= i21
->logon_count
;
974 i
->usri3_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
975 i
->usri3_country_code
= i21
->country_code
;
976 i
->usri3_code_page
= i21
->code_page
;
977 i
->usri3_user_id
= i21
->rid
;
978 i
->usri3_primary_group_id
= i21
->primary_gid
;
979 i
->usri3_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
980 i
->usri3_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
981 i
->usri3_password_expired
= i21
->password_expired
;
986 /****************************************************************
987 ****************************************************************/
989 static NTSTATUS
info21_to_USER_INFO_4(TALLOC_CTX
*mem_ctx
,
990 const struct samr_UserInfo21
*i21
,
992 struct dom_sid
*domain_sid
,
993 struct USER_INFO_4
*i
)
999 i
->usri4_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1000 NT_STATUS_HAVE_NO_MEMORY(i
->usri4_name
);
1001 i
->usri4_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
1002 i
->usri4_password
= NULL
;
1003 i
->usri4_priv
= samr_rid_to_priv_level(i21
->rid
);
1004 i
->usri4_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
1005 i
->usri4_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1006 i
->usri4_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1007 i
->usri4_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
1008 i
->usri4_auth_flags
= auth_flag
;
1009 i
->usri4_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1010 i
->usri4_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1011 i
->usri4_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1012 i
->usri4_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1013 i
->usri4_last_logon
= nt_time_to_unix(i21
->last_logon
);
1014 i
->usri4_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1015 i
->usri4_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
1016 i
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1017 i
->usri4_units_per_week
= i21
->logon_hours
.units_per_week
;
1018 i
->usri4_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1019 i
->usri4_bad_pw_count
= i21
->bad_password_count
;
1020 i
->usri4_num_logons
= i21
->logon_count
;
1021 i
->usri4_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1022 i
->usri4_country_code
= i21
->country_code
;
1023 i
->usri4_code_page
= i21
->code_page
;
1024 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1025 return NT_STATUS_NO_MEMORY
;
1027 i
->usri4_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1028 i
->usri4_primary_group_id
= i21
->primary_gid
;
1029 i
->usri4_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
1030 i
->usri4_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
1031 i
->usri4_password_expired
= i21
->password_expired
;
1033 return NT_STATUS_OK
;
1036 /****************************************************************
1037 ****************************************************************/
1039 static NTSTATUS
info21_to_USER_INFO_10(TALLOC_CTX
*mem_ctx
,
1040 const struct samr_UserInfo21
*i21
,
1041 struct USER_INFO_10
*i
)
1045 i
->usri10_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1046 NT_STATUS_HAVE_NO_MEMORY(i
->usri10_name
);
1047 i
->usri10_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1048 i
->usri10_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1049 i
->usri10_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1051 return NT_STATUS_OK
;
1054 /****************************************************************
1055 ****************************************************************/
1057 static NTSTATUS
info21_to_USER_INFO_11(TALLOC_CTX
*mem_ctx
,
1058 const struct samr_UserInfo21
*i21
,
1060 struct USER_INFO_11
*i
)
1064 i
->usri11_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1065 NT_STATUS_HAVE_NO_MEMORY(i
->usri11_name
);
1066 i
->usri11_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1067 i
->usri11_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1068 i
->usri11_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1069 i
->usri11_priv
= samr_rid_to_priv_level(i21
->rid
);
1070 i
->usri11_auth_flags
= auth_flag
;
1071 i
->usri11_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
1072 i
->usri11_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
1073 i
->usri11_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1074 i
->usri11_last_logon
= nt_time_to_unix(i21
->last_logon
);
1075 i
->usri11_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1076 i
->usri11_bad_pw_count
= i21
->bad_password_count
;
1077 i
->usri11_num_logons
= i21
->logon_count
;
1078 i
->usri11_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1079 i
->usri11_country_code
= i21
->country_code
;
1080 i
->usri11_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1081 i
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1082 i
->usri11_units_per_week
= i21
->logon_hours
.units_per_week
;
1083 i
->usri11_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1084 i
->usri11_code_page
= i21
->code_page
;
1086 return NT_STATUS_OK
;
1089 /****************************************************************
1090 ****************************************************************/
1092 static NTSTATUS
info21_to_USER_INFO_20(TALLOC_CTX
*mem_ctx
,
1093 const struct samr_UserInfo21
*i21
,
1094 struct USER_INFO_20
*i
)
1098 i
->usri20_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1099 NT_STATUS_HAVE_NO_MEMORY(i
->usri20_name
);
1100 i
->usri20_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1101 i
->usri20_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1102 i
->usri20_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1103 i
->usri20_user_id
= i21
->rid
;
1105 return NT_STATUS_OK
;
1108 /****************************************************************
1109 ****************************************************************/
1111 static NTSTATUS
info21_to_USER_INFO_23(TALLOC_CTX
*mem_ctx
,
1112 const struct samr_UserInfo21
*i21
,
1113 struct dom_sid
*domain_sid
,
1114 struct USER_INFO_23
*i
)
1120 i
->usri23_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1121 NT_STATUS_HAVE_NO_MEMORY(i
->usri23_name
);
1122 i
->usri23_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1123 i
->usri23_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1124 i
->usri23_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1125 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1126 return NT_STATUS_NO_MEMORY
;
1128 i
->usri23_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1130 return NT_STATUS_OK
;
1133 /****************************************************************
1134 ****************************************************************/
1136 static NTSTATUS
libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX
*mem_ctx
,
1137 struct rpc_pipe_client
*pipe_cli
,
1138 struct dom_sid
*domain_sid
,
1139 struct policy_handle
*domain_handle
,
1140 struct policy_handle
*builtin_handle
,
1141 const char *user_name
,
1145 uint32_t *num_entries
)
1149 struct samr_UserInfo21
*info21
= NULL
;
1150 struct sec_desc_buf
*sec_desc
= NULL
;
1151 uint32_t auth_flag
= 0;
1153 struct USER_INFO_0 info0
;
1154 struct USER_INFO_1 info1
;
1155 struct USER_INFO_2 info2
;
1156 struct USER_INFO_3 info3
;
1157 struct USER_INFO_4 info4
;
1158 struct USER_INFO_10 info10
;
1159 struct USER_INFO_11 info11
;
1160 struct USER_INFO_20 info20
;
1161 struct USER_INFO_23 info23
;
1175 return NT_STATUS_INVALID_LEVEL
;
1179 info0
.usri0_name
= talloc_strdup(mem_ctx
, user_name
);
1180 NT_STATUS_HAVE_NO_MEMORY(info0
.usri0_name
);
1182 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_0
, info0
,
1183 (struct USER_INFO_0
**)buffer
, num_entries
);
1185 return NT_STATUS_OK
;
1188 status
= libnetapi_samr_lookup_user(mem_ctx
, pipe_cli
,
1199 if (!NT_STATUS_IS_OK(status
)) {
1205 /* already returned above */
1208 status
= info21_to_USER_INFO_1(mem_ctx
, info21
, &info1
);
1209 NT_STATUS_NOT_OK_RETURN(status
);
1211 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_1
, info1
,
1212 (struct USER_INFO_1
**)buffer
, num_entries
);
1216 status
= info21_to_USER_INFO_2(mem_ctx
, info21
, auth_flag
, &info2
);
1217 NT_STATUS_NOT_OK_RETURN(status
);
1219 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_2
, info2
,
1220 (struct USER_INFO_2
**)buffer
, num_entries
);
1224 status
= info21_to_USER_INFO_3(mem_ctx
, info21
, auth_flag
, &info3
);
1225 NT_STATUS_NOT_OK_RETURN(status
);
1227 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_3
, info3
,
1228 (struct USER_INFO_3
**)buffer
, num_entries
);
1232 status
= info21_to_USER_INFO_4(mem_ctx
, info21
, auth_flag
, domain_sid
, &info4
);
1233 NT_STATUS_NOT_OK_RETURN(status
);
1235 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_4
, info4
,
1236 (struct USER_INFO_4
**)buffer
, num_entries
);
1240 status
= info21_to_USER_INFO_10(mem_ctx
, info21
, &info10
);
1241 NT_STATUS_NOT_OK_RETURN(status
);
1243 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_10
, info10
,
1244 (struct USER_INFO_10
**)buffer
, num_entries
);
1248 status
= info21_to_USER_INFO_11(mem_ctx
, info21
, auth_flag
, &info11
);
1249 NT_STATUS_NOT_OK_RETURN(status
);
1251 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_11
, info11
,
1252 (struct USER_INFO_11
**)buffer
, num_entries
);
1256 status
= info21_to_USER_INFO_20(mem_ctx
, info21
, &info20
);
1257 NT_STATUS_NOT_OK_RETURN(status
);
1259 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_20
, info20
,
1260 (struct USER_INFO_20
**)buffer
, num_entries
);
1264 status
= info21_to_USER_INFO_23(mem_ctx
, info21
, domain_sid
, &info23
);
1265 NT_STATUS_NOT_OK_RETURN(status
);
1267 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_23
, info23
,
1268 (struct USER_INFO_23
**)buffer
, num_entries
);
1271 return NT_STATUS_INVALID_LEVEL
;
1278 /****************************************************************
1279 ****************************************************************/
1281 WERROR
NetUserEnum_r(struct libnetapi_ctx
*ctx
,
1282 struct NetUserEnum
*r
)
1284 struct rpc_pipe_client
*pipe_cli
= NULL
;
1285 struct policy_handle connect_handle
;
1286 struct dom_sid2
*domain_sid
= NULL
;
1287 struct policy_handle domain_handle
, builtin_handle
;
1288 struct samr_SamArray
*sam
= NULL
;
1289 uint32_t filter
= ACB_NORMAL
;
1291 uint32_t entries_read
= 0;
1293 NTSTATUS status
= NT_STATUS_OK
;
1294 NTSTATUS result
= NT_STATUS_OK
;
1296 struct dcerpc_binding_handle
*b
= NULL
;
1298 ZERO_STRUCT(connect_handle
);
1299 ZERO_STRUCT(domain_handle
);
1300 ZERO_STRUCT(builtin_handle
);
1302 if (!r
->out
.buffer
) {
1303 return WERR_INVALID_PARAM
;
1306 *r
->out
.buffer
= NULL
;
1307 *r
->out
.entries_read
= 0;
1309 switch (r
->in
.level
) {
1321 return WERR_UNKNOWN_LEVEL
;
1324 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1325 &ndr_table_samr
.syntax_id
,
1327 if (!W_ERROR_IS_OK(werr
)) {
1331 b
= pipe_cli
->binding_handle
;
1333 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1334 SAMR_ACCESS_ENUM_DOMAINS
|
1335 SAMR_ACCESS_LOOKUP_DOMAIN
,
1336 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1337 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1340 if (!W_ERROR_IS_OK(werr
)) {
1344 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1345 SAMR_ACCESS_ENUM_DOMAINS
|
1346 SAMR_ACCESS_LOOKUP_DOMAIN
,
1347 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1348 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1349 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1353 if (!W_ERROR_IS_OK(werr
)) {
1357 switch (r
->in
.filter
) {
1358 case FILTER_NORMAL_ACCOUNT
:
1359 filter
= ACB_NORMAL
;
1361 case FILTER_TEMP_DUPLICATE_ACCOUNT
:
1362 filter
= ACB_TEMPDUP
;
1364 case FILTER_INTERDOMAIN_TRUST_ACCOUNT
:
1365 filter
= ACB_DOMTRUST
;
1367 case FILTER_WORKSTATION_TRUST_ACCOUNT
:
1368 filter
= ACB_WSTRUST
;
1370 case FILTER_SERVER_TRUST_ACCOUNT
:
1371 filter
= ACB_SVRTRUST
;
1377 status
= dcerpc_samr_EnumDomainUsers(b
,
1380 r
->in
.resume_handle
,
1386 if (!NT_STATUS_IS_OK(status
)) {
1387 werr
= ntstatus_to_werror(status
);
1390 werr
= ntstatus_to_werror(result
);
1391 if (NT_STATUS_IS_ERR(result
)) {
1395 for (i
=0; i
< sam
->count
; i
++) {
1397 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1401 sam
->entries
[i
].name
.string
,
1402 sam
->entries
[i
].idx
,
1405 r
->out
.entries_read
);
1406 if (!NT_STATUS_IS_OK(status
)) {
1407 werr
= ntstatus_to_werror(status
);
1414 if (NT_STATUS_IS_OK(result
) ||
1415 NT_STATUS_IS_ERR(result
)) {
1417 if (ctx
->disable_policy_handle_cache
) {
1418 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1419 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1420 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1427 /****************************************************************
1428 ****************************************************************/
1430 WERROR
NetUserEnum_l(struct libnetapi_ctx
*ctx
,
1431 struct NetUserEnum
*r
)
1433 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserEnum
);
1436 /****************************************************************
1437 ****************************************************************/
1439 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX
*mem_ctx
,
1440 struct samr_DispInfoGeneral
*info
,
1441 uint32_t *entries_read
,
1444 struct NET_DISPLAY_USER
*user
= NULL
;
1447 user
= TALLOC_ZERO_ARRAY(mem_ctx
,
1448 struct NET_DISPLAY_USER
,
1450 W_ERROR_HAVE_NO_MEMORY(user
);
1452 for (i
= 0; i
< info
->count
; i
++) {
1453 user
[i
].usri1_name
= talloc_strdup(mem_ctx
,
1454 info
->entries
[i
].account_name
.string
);
1455 user
[i
].usri1_comment
= talloc_strdup(mem_ctx
,
1456 info
->entries
[i
].description
.string
);
1457 user
[i
].usri1_flags
=
1458 info
->entries
[i
].acct_flags
;
1459 user
[i
].usri1_full_name
= talloc_strdup(mem_ctx
,
1460 info
->entries
[i
].full_name
.string
);
1461 user
[i
].usri1_user_id
=
1462 info
->entries
[i
].rid
;
1463 user
[i
].usri1_next_index
=
1464 info
->entries
[i
].idx
;
1466 if (!user
[i
].usri1_name
) {
1471 *buffer
= talloc_memdup(mem_ctx
, user
,
1472 sizeof(struct NET_DISPLAY_USER
) * info
->count
);
1473 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1475 *entries_read
= info
->count
;
1480 /****************************************************************
1481 ****************************************************************/
1483 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX
*mem_ctx
,
1484 struct samr_DispInfoFull
*info
,
1485 uint32_t *entries_read
,
1488 struct NET_DISPLAY_MACHINE
*machine
= NULL
;
1491 machine
= TALLOC_ZERO_ARRAY(mem_ctx
,
1492 struct NET_DISPLAY_MACHINE
,
1494 W_ERROR_HAVE_NO_MEMORY(machine
);
1496 for (i
= 0; i
< info
->count
; i
++) {
1497 machine
[i
].usri2_name
= talloc_strdup(mem_ctx
,
1498 info
->entries
[i
].account_name
.string
);
1499 machine
[i
].usri2_comment
= talloc_strdup(mem_ctx
,
1500 info
->entries
[i
].description
.string
);
1501 machine
[i
].usri2_flags
=
1502 info
->entries
[i
].acct_flags
;
1503 machine
[i
].usri2_user_id
=
1504 info
->entries
[i
].rid
;
1505 machine
[i
].usri2_next_index
=
1506 info
->entries
[i
].idx
;
1508 if (!machine
[i
].usri2_name
) {
1513 *buffer
= talloc_memdup(mem_ctx
, machine
,
1514 sizeof(struct NET_DISPLAY_MACHINE
) * info
->count
);
1515 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1517 *entries_read
= info
->count
;
1522 /****************************************************************
1523 ****************************************************************/
1525 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX
*mem_ctx
,
1526 struct samr_DispInfoFullGroups
*info
,
1527 uint32_t *entries_read
,
1530 struct NET_DISPLAY_GROUP
*group
= NULL
;
1533 group
= TALLOC_ZERO_ARRAY(mem_ctx
,
1534 struct NET_DISPLAY_GROUP
,
1536 W_ERROR_HAVE_NO_MEMORY(group
);
1538 for (i
= 0; i
< info
->count
; i
++) {
1539 group
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1540 info
->entries
[i
].account_name
.string
);
1541 group
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1542 info
->entries
[i
].description
.string
);
1543 group
[i
].grpi3_group_id
=
1544 info
->entries
[i
].rid
;
1545 group
[i
].grpi3_attributes
=
1546 info
->entries
[i
].acct_flags
;
1547 group
[i
].grpi3_next_index
=
1548 info
->entries
[i
].idx
;
1550 if (!group
[i
].grpi3_name
) {
1555 *buffer
= talloc_memdup(mem_ctx
, group
,
1556 sizeof(struct NET_DISPLAY_GROUP
) * info
->count
);
1557 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1559 *entries_read
= info
->count
;
1565 /****************************************************************
1566 ****************************************************************/
1568 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX
*mem_ctx
,
1569 union samr_DispInfo
*info
,
1571 uint32_t *entries_read
,
1576 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx
,
1581 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx
,
1586 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx
,
1594 return WERR_UNKNOWN_LEVEL
;
1597 /****************************************************************
1598 ****************************************************************/
1600 WERROR
NetQueryDisplayInformation_r(struct libnetapi_ctx
*ctx
,
1601 struct NetQueryDisplayInformation
*r
)
1603 struct rpc_pipe_client
*pipe_cli
= NULL
;
1604 struct policy_handle connect_handle
;
1605 struct dom_sid2
*domain_sid
= NULL
;
1606 struct policy_handle domain_handle
;
1607 union samr_DispInfo info
;
1608 struct dcerpc_binding_handle
*b
= NULL
;
1610 uint32_t total_size
= 0;
1611 uint32_t returned_size
= 0;
1613 NTSTATUS status
= NT_STATUS_OK
;
1614 NTSTATUS result
= NT_STATUS_OK
;
1618 *r
->out
.entries_read
= 0;
1620 ZERO_STRUCT(connect_handle
);
1621 ZERO_STRUCT(domain_handle
);
1623 switch (r
->in
.level
) {
1629 return WERR_UNKNOWN_LEVEL
;
1632 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1633 &ndr_table_samr
.syntax_id
,
1635 if (!W_ERROR_IS_OK(werr
)) {
1639 b
= pipe_cli
->binding_handle
;
1641 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1642 SAMR_ACCESS_ENUM_DOMAINS
|
1643 SAMR_ACCESS_LOOKUP_DOMAIN
,
1644 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1645 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1646 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1650 if (!W_ERROR_IS_OK(werr
)) {
1654 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1659 r
->in
.entries_requested
,
1665 if (!NT_STATUS_IS_OK(status
)) {
1666 werr
= ntstatus_to_werror(status
);
1669 werr
= ntstatus_to_werror(result
);
1670 if (NT_STATUS_IS_ERR(result
)) {
1674 werr_tmp
= convert_samr_dispinfo_to_NET_DISPLAY(ctx
, &info
,
1676 r
->out
.entries_read
,
1678 if (!W_ERROR_IS_OK(werr_tmp
)) {
1683 if (NT_STATUS_IS_OK(result
) ||
1684 NT_STATUS_IS_ERR(result
)) {
1686 if (ctx
->disable_policy_handle_cache
) {
1687 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1688 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1696 /****************************************************************
1697 ****************************************************************/
1700 WERROR
NetQueryDisplayInformation_l(struct libnetapi_ctx
*ctx
,
1701 struct NetQueryDisplayInformation
*r
)
1703 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetQueryDisplayInformation
);
1706 /****************************************************************
1707 ****************************************************************/
1709 WERROR
NetUserChangePassword_r(struct libnetapi_ctx
*ctx
,
1710 struct NetUserChangePassword
*r
)
1712 return WERR_NOT_SUPPORTED
;
1715 /****************************************************************
1716 ****************************************************************/
1718 WERROR
NetUserChangePassword_l(struct libnetapi_ctx
*ctx
,
1719 struct NetUserChangePassword
*r
)
1721 return WERR_NOT_SUPPORTED
;
1724 /****************************************************************
1725 ****************************************************************/
1727 WERROR
NetUserGetInfo_r(struct libnetapi_ctx
*ctx
,
1728 struct NetUserGetInfo
*r
)
1730 struct rpc_pipe_client
*pipe_cli
= NULL
;
1731 NTSTATUS status
, result
;
1734 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1735 struct lsa_String lsa_account_name
;
1736 struct dom_sid2
*domain_sid
= NULL
;
1737 struct samr_Ids user_rids
, name_types
;
1738 uint32_t num_entries
= 0;
1739 struct dcerpc_binding_handle
*b
= NULL
;
1741 ZERO_STRUCT(connect_handle
);
1742 ZERO_STRUCT(domain_handle
);
1743 ZERO_STRUCT(builtin_handle
);
1744 ZERO_STRUCT(user_handle
);
1746 if (!r
->out
.buffer
) {
1747 return WERR_INVALID_PARAM
;
1750 switch (r
->in
.level
) {
1762 werr
= WERR_UNKNOWN_LEVEL
;
1766 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1767 &ndr_table_samr
.syntax_id
,
1769 if (!W_ERROR_IS_OK(werr
)) {
1773 b
= pipe_cli
->binding_handle
;
1775 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1776 SAMR_ACCESS_ENUM_DOMAINS
|
1777 SAMR_ACCESS_LOOKUP_DOMAIN
,
1778 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1782 if (!W_ERROR_IS_OK(werr
)) {
1786 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1787 SAMR_ACCESS_ENUM_DOMAINS
|
1788 SAMR_ACCESS_LOOKUP_DOMAIN
,
1789 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1790 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1793 if (!W_ERROR_IS_OK(werr
)) {
1797 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1799 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1806 if (!NT_STATUS_IS_OK(status
)) {
1807 werr
= ntstatus_to_werror(status
);
1810 if (!NT_STATUS_IS_OK(result
)) {
1811 werr
= ntstatus_to_werror(result
);
1814 if (user_rids
.count
!= 1) {
1815 werr
= WERR_BAD_NET_RESP
;
1818 if (name_types
.count
!= 1) {
1819 werr
= WERR_BAD_NET_RESP
;
1823 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1832 if (!NT_STATUS_IS_OK(status
)) {
1833 werr
= ntstatus_to_werror(status
);
1838 if (is_valid_policy_hnd(&user_handle
) && b
) {
1839 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1842 if (ctx
->disable_policy_handle_cache
) {
1843 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1844 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1850 /****************************************************************
1851 ****************************************************************/
1853 WERROR
NetUserGetInfo_l(struct libnetapi_ctx
*ctx
,
1854 struct NetUserGetInfo
*r
)
1856 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetInfo
);
1859 /****************************************************************
1860 ****************************************************************/
1862 WERROR
NetUserSetInfo_r(struct libnetapi_ctx
*ctx
,
1863 struct NetUserSetInfo
*r
)
1865 struct rpc_pipe_client
*pipe_cli
= NULL
;
1866 NTSTATUS status
, result
;
1869 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1870 struct lsa_String lsa_account_name
;
1871 struct dom_sid2
*domain_sid
= NULL
;
1872 struct samr_Ids user_rids
, name_types
;
1873 uint32_t user_mask
= 0;
1875 struct USER_INFO_X uX
;
1876 struct dcerpc_binding_handle
*b
= NULL
;
1877 DATA_BLOB session_key
;
1879 ZERO_STRUCT(connect_handle
);
1880 ZERO_STRUCT(domain_handle
);
1881 ZERO_STRUCT(builtin_handle
);
1882 ZERO_STRUCT(user_handle
);
1884 if (!r
->in
.buffer
) {
1885 return WERR_INVALID_PARAM
;
1888 switch (r
->in
.level
) {
1890 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1893 user_mask
= SAMR_USER_ACCESS_SET_PASSWORD
;
1902 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1906 user_mask
= SAMR_USER_ACCESS_SET_LOC_COM
;
1908 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1909 SAMR_USER_ACCESS_GET_GROUPS
;
1912 user_mask
= SEC_STD_READ_CONTROL
|
1914 SAMR_USER_ACCESS_GET_GROUPS
|
1915 SAMR_USER_ACCESS_SET_PASSWORD
|
1916 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1917 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
1918 SAMR_USER_ACCESS_SET_LOC_COM
;
1930 werr
= WERR_NOT_SUPPORTED
;
1933 werr
= WERR_UNKNOWN_LEVEL
;
1937 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1938 &ndr_table_samr
.syntax_id
,
1940 if (!W_ERROR_IS_OK(werr
)) {
1944 b
= pipe_cli
->binding_handle
;
1946 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1947 SAMR_ACCESS_ENUM_DOMAINS
|
1948 SAMR_ACCESS_LOOKUP_DOMAIN
,
1949 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
1950 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1954 if (!W_ERROR_IS_OK(werr
)) {
1958 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1959 SAMR_ACCESS_ENUM_DOMAINS
|
1960 SAMR_ACCESS_LOOKUP_DOMAIN
,
1961 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1962 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1965 if (!W_ERROR_IS_OK(werr
)) {
1969 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1971 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1978 if (!NT_STATUS_IS_OK(status
)) {
1979 werr
= ntstatus_to_werror(status
);
1982 if (!NT_STATUS_IS_OK(result
)) {
1983 werr
= ntstatus_to_werror(result
);
1986 if (user_rids
.count
!= 1) {
1987 werr
= WERR_BAD_NET_RESP
;
1990 if (name_types
.count
!= 1) {
1991 werr
= WERR_BAD_NET_RESP
;
1995 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
2001 if (!NT_STATUS_IS_OK(status
)) {
2002 werr
= ntstatus_to_werror(status
);
2005 if (!NT_STATUS_IS_OK(result
)) {
2006 werr
= ntstatus_to_werror(result
);
2010 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
2011 if (!NT_STATUS_IS_OK(status
)) {
2012 werr
= ntstatus_to_werror(status
);
2016 status
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
2017 if (!NT_STATUS_IS_OK(status
)) {
2018 werr
= ntstatus_to_werror(status
);
2022 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
2026 if (!NT_STATUS_IS_OK(status
)) {
2027 werr
= ntstatus_to_werror(status
);
2034 if (is_valid_policy_hnd(&user_handle
) && b
) {
2035 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
2038 if (ctx
->disable_policy_handle_cache
) {
2039 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2040 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
2041 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2047 /****************************************************************
2048 ****************************************************************/
2050 WERROR
NetUserSetInfo_l(struct libnetapi_ctx
*ctx
,
2051 struct NetUserSetInfo
*r
)
2053 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetInfo
);
2056 /****************************************************************
2057 ****************************************************************/
2059 static NTSTATUS
query_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2060 struct rpc_pipe_client
*pipe_cli
,
2061 struct policy_handle
*domain_handle
,
2062 struct samr_DomInfo1
*info1
,
2063 struct samr_DomInfo3
*info3
,
2064 struct samr_DomInfo5
*info5
,
2065 struct samr_DomInfo6
*info6
,
2066 struct samr_DomInfo7
*info7
,
2067 struct samr_DomInfo12
*info12
)
2069 NTSTATUS status
, result
;
2070 union samr_DomainInfo
*dom_info
= NULL
;
2071 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2074 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2079 NT_STATUS_NOT_OK_RETURN(status
);
2080 NT_STATUS_NOT_OK_RETURN(result
);
2082 *info1
= dom_info
->info1
;
2086 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2091 NT_STATUS_NOT_OK_RETURN(status
);
2092 NT_STATUS_NOT_OK_RETURN(result
);
2094 *info3
= dom_info
->info3
;
2098 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2103 NT_STATUS_NOT_OK_RETURN(status
);
2104 NT_STATUS_NOT_OK_RETURN(result
);
2106 *info5
= dom_info
->info5
;
2110 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2115 NT_STATUS_NOT_OK_RETURN(status
);
2116 NT_STATUS_NOT_OK_RETURN(result
);
2118 *info6
= dom_info
->info6
;
2122 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2127 NT_STATUS_NOT_OK_RETURN(status
);
2128 NT_STATUS_NOT_OK_RETURN(result
);
2130 *info7
= dom_info
->info7
;
2134 status
= dcerpc_samr_QueryDomainInfo2(b
, mem_ctx
,
2139 NT_STATUS_NOT_OK_RETURN(status
);
2140 NT_STATUS_NOT_OK_RETURN(result
);
2142 *info12
= dom_info
->info12
;
2145 return NT_STATUS_OK
;
2148 /****************************************************************
2149 ****************************************************************/
2151 static NTSTATUS
query_USER_MODALS_INFO_0(TALLOC_CTX
*mem_ctx
,
2152 struct rpc_pipe_client
*pipe_cli
,
2153 struct policy_handle
*domain_handle
,
2154 struct USER_MODALS_INFO_0
*info0
)
2157 struct samr_DomInfo1 dom_info1
;
2158 struct samr_DomInfo3 dom_info3
;
2160 ZERO_STRUCTP(info0
);
2162 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2171 NT_STATUS_NOT_OK_RETURN(status
);
2173 info0
->usrmod0_min_passwd_len
=
2174 dom_info1
.min_password_length
;
2175 info0
->usrmod0_max_passwd_age
=
2176 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.max_password_age
);
2177 info0
->usrmod0_min_passwd_age
=
2178 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.min_password_age
);
2179 info0
->usrmod0_password_hist_len
=
2180 dom_info1
.password_history_length
;
2182 info0
->usrmod0_force_logoff
=
2183 nt_time_to_unix_abs(&dom_info3
.force_logoff_time
);
2185 return NT_STATUS_OK
;
2188 /****************************************************************
2189 ****************************************************************/
2191 static NTSTATUS
query_USER_MODALS_INFO_1(TALLOC_CTX
*mem_ctx
,
2192 struct rpc_pipe_client
*pipe_cli
,
2193 struct policy_handle
*domain_handle
,
2194 struct USER_MODALS_INFO_1
*info1
)
2197 struct samr_DomInfo6 dom_info6
;
2198 struct samr_DomInfo7 dom_info7
;
2200 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2209 NT_STATUS_NOT_OK_RETURN(status
);
2211 info1
->usrmod1_primary
=
2212 talloc_strdup(mem_ctx
, dom_info6
.primary
.string
);
2214 info1
->usrmod1_role
= dom_info7
.role
;
2216 return NT_STATUS_OK
;
2219 /****************************************************************
2220 ****************************************************************/
2222 static NTSTATUS
query_USER_MODALS_INFO_2(TALLOC_CTX
*mem_ctx
,
2223 struct rpc_pipe_client
*pipe_cli
,
2224 struct policy_handle
*domain_handle
,
2225 struct dom_sid
*domain_sid
,
2226 struct USER_MODALS_INFO_2
*info2
)
2229 struct samr_DomInfo5 dom_info5
;
2231 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2240 NT_STATUS_NOT_OK_RETURN(status
);
2242 info2
->usrmod2_domain_name
=
2243 talloc_strdup(mem_ctx
, dom_info5
.domain_name
.string
);
2244 info2
->usrmod2_domain_id
=
2245 (struct domsid
*)dom_sid_dup(mem_ctx
, domain_sid
);
2247 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_name
);
2248 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_id
);
2250 return NT_STATUS_OK
;
2253 /****************************************************************
2254 ****************************************************************/
2256 static NTSTATUS
query_USER_MODALS_INFO_3(TALLOC_CTX
*mem_ctx
,
2257 struct rpc_pipe_client
*pipe_cli
,
2258 struct policy_handle
*domain_handle
,
2259 struct USER_MODALS_INFO_3
*info3
)
2262 struct samr_DomInfo12 dom_info12
;
2264 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2273 NT_STATUS_NOT_OK_RETURN(status
);
2275 info3
->usrmod3_lockout_duration
=
2276 nt_time_to_unix_abs(&dom_info12
.lockout_duration
);
2277 info3
->usrmod3_lockout_observation_window
=
2278 nt_time_to_unix_abs(&dom_info12
.lockout_window
);
2279 info3
->usrmod3_lockout_threshold
=
2280 dom_info12
.lockout_threshold
;
2282 return NT_STATUS_OK
;
2285 /****************************************************************
2286 ****************************************************************/
2288 static NTSTATUS
query_USER_MODALS_INFO_to_buffer(TALLOC_CTX
*mem_ctx
,
2289 struct rpc_pipe_client
*pipe_cli
,
2291 struct policy_handle
*domain_handle
,
2292 struct dom_sid
*domain_sid
,
2297 struct USER_MODALS_INFO_0 info0
;
2298 struct USER_MODALS_INFO_1 info1
;
2299 struct USER_MODALS_INFO_2 info2
;
2300 struct USER_MODALS_INFO_3 info3
;
2303 return ERROR_INSUFFICIENT_BUFFER
;
2308 status
= query_USER_MODALS_INFO_0(mem_ctx
,
2312 NT_STATUS_NOT_OK_RETURN(status
);
2314 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
,
2319 status
= query_USER_MODALS_INFO_1(mem_ctx
,
2323 NT_STATUS_NOT_OK_RETURN(status
);
2325 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
,
2329 status
= query_USER_MODALS_INFO_2(mem_ctx
,
2334 NT_STATUS_NOT_OK_RETURN(status
);
2336 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
,
2340 status
= query_USER_MODALS_INFO_3(mem_ctx
,
2344 NT_STATUS_NOT_OK_RETURN(status
);
2346 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
,
2353 NT_STATUS_HAVE_NO_MEMORY(*buffer
);
2355 return NT_STATUS_OK
;
2358 /****************************************************************
2359 ****************************************************************/
2361 WERROR
NetUserModalsGet_r(struct libnetapi_ctx
*ctx
,
2362 struct NetUserModalsGet
*r
)
2364 struct rpc_pipe_client
*pipe_cli
= NULL
;
2368 struct policy_handle connect_handle
, domain_handle
;
2369 struct dom_sid2
*domain_sid
= NULL
;
2370 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2372 ZERO_STRUCT(connect_handle
);
2373 ZERO_STRUCT(domain_handle
);
2375 if (!r
->out
.buffer
) {
2376 return WERR_INVALID_PARAM
;
2379 switch (r
->in
.level
) {
2381 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2382 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2386 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2389 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
2392 werr
= WERR_UNKNOWN_LEVEL
;
2396 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2397 &ndr_table_samr
.syntax_id
,
2399 if (!W_ERROR_IS_OK(werr
)) {
2403 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2404 SAMR_ACCESS_ENUM_DOMAINS
|
2405 SAMR_ACCESS_LOOKUP_DOMAIN
,
2410 if (!W_ERROR_IS_OK(werr
)) {
2417 /* 3: 12 (DomainInfo2) */
2419 status
= query_USER_MODALS_INFO_to_buffer(ctx
,
2425 if (!NT_STATUS_IS_OK(status
)) {
2426 werr
= ntstatus_to_werror(status
);
2431 if (ctx
->disable_policy_handle_cache
) {
2432 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2433 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2439 /****************************************************************
2440 ****************************************************************/
2442 WERROR
NetUserModalsGet_l(struct libnetapi_ctx
*ctx
,
2443 struct NetUserModalsGet
*r
)
2445 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsGet
);
2448 /****************************************************************
2449 ****************************************************************/
2451 static NTSTATUS
set_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2452 struct rpc_pipe_client
*pipe_cli
,
2453 struct policy_handle
*domain_handle
,
2454 struct samr_DomInfo1
*info1
,
2455 struct samr_DomInfo3
*info3
,
2456 struct samr_DomInfo12
*info12
)
2458 NTSTATUS status
, result
;
2459 union samr_DomainInfo dom_info
;
2460 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2464 ZERO_STRUCT(dom_info
);
2466 dom_info
.info1
= *info1
;
2468 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2473 NT_STATUS_NOT_OK_RETURN(status
);
2474 NT_STATUS_NOT_OK_RETURN(result
);
2479 ZERO_STRUCT(dom_info
);
2481 dom_info
.info3
= *info3
;
2483 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2489 NT_STATUS_NOT_OK_RETURN(status
);
2490 NT_STATUS_NOT_OK_RETURN(result
);
2495 ZERO_STRUCT(dom_info
);
2497 dom_info
.info12
= *info12
;
2499 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2505 NT_STATUS_NOT_OK_RETURN(status
);
2506 NT_STATUS_NOT_OK_RETURN(result
);
2509 return NT_STATUS_OK
;
2512 /****************************************************************
2513 ****************************************************************/
2515 static NTSTATUS
set_USER_MODALS_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
2516 struct rpc_pipe_client
*pipe_cli
,
2517 struct policy_handle
*domain_handle
,
2518 struct USER_MODALS_INFO_0
*info0
)
2521 struct samr_DomInfo1 dom_info_1
;
2522 struct samr_DomInfo3 dom_info_3
;
2524 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2533 NT_STATUS_NOT_OK_RETURN(status
);
2535 dom_info_1
.min_password_length
=
2536 info0
->usrmod0_min_passwd_len
;
2537 dom_info_1
.password_history_length
=
2538 info0
->usrmod0_password_hist_len
;
2540 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2541 info0
->usrmod0_max_passwd_age
);
2542 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2543 info0
->usrmod0_min_passwd_age
);
2545 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2546 info0
->usrmod0_force_logoff
);
2548 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2556 /****************************************************************
2557 ****************************************************************/
2559 static NTSTATUS
set_USER_MODALS_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
2560 struct rpc_pipe_client
*pipe_cli
,
2561 struct policy_handle
*domain_handle
,
2562 struct USER_MODALS_INFO_3
*info3
)
2565 struct samr_DomInfo12 dom_info_12
;
2567 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2576 NT_STATUS_NOT_OK_RETURN(status
);
2578 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_duration
,
2579 info3
->usrmod3_lockout_duration
);
2580 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_window
,
2581 info3
->usrmod3_lockout_observation_window
);
2582 dom_info_12
.lockout_threshold
= info3
->usrmod3_lockout_threshold
;
2584 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2592 /****************************************************************
2593 ****************************************************************/
2595 static NTSTATUS
set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX
*mem_ctx
,
2596 struct rpc_pipe_client
*pipe_cli
,
2597 struct policy_handle
*domain_handle
,
2598 struct USER_MODALS_INFO_1001
*info1001
)
2601 struct samr_DomInfo1 dom_info_1
;
2603 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2612 NT_STATUS_NOT_OK_RETURN(status
);
2614 dom_info_1
.min_password_length
=
2615 info1001
->usrmod1001_min_passwd_len
;
2617 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2625 /****************************************************************
2626 ****************************************************************/
2628 static NTSTATUS
set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX
*mem_ctx
,
2629 struct rpc_pipe_client
*pipe_cli
,
2630 struct policy_handle
*domain_handle
,
2631 struct USER_MODALS_INFO_1002
*info1002
)
2634 struct samr_DomInfo1 dom_info_1
;
2636 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2645 NT_STATUS_NOT_OK_RETURN(status
);
2647 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2648 info1002
->usrmod1002_max_passwd_age
);
2650 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2658 /****************************************************************
2659 ****************************************************************/
2661 static NTSTATUS
set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX
*mem_ctx
,
2662 struct rpc_pipe_client
*pipe_cli
,
2663 struct policy_handle
*domain_handle
,
2664 struct USER_MODALS_INFO_1003
*info1003
)
2667 struct samr_DomInfo1 dom_info_1
;
2669 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2678 NT_STATUS_NOT_OK_RETURN(status
);
2680 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2681 info1003
->usrmod1003_min_passwd_age
);
2683 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2691 /****************************************************************
2692 ****************************************************************/
2694 static NTSTATUS
set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX
*mem_ctx
,
2695 struct rpc_pipe_client
*pipe_cli
,
2696 struct policy_handle
*domain_handle
,
2697 struct USER_MODALS_INFO_1004
*info1004
)
2700 struct samr_DomInfo3 dom_info_3
;
2702 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2711 NT_STATUS_NOT_OK_RETURN(status
);
2713 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2714 info1004
->usrmod1004_force_logoff
);
2716 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2724 /****************************************************************
2725 ****************************************************************/
2727 static NTSTATUS
set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX
*mem_ctx
,
2728 struct rpc_pipe_client
*pipe_cli
,
2729 struct policy_handle
*domain_handle
,
2730 struct USER_MODALS_INFO_1005
*info1005
)
2733 struct samr_DomInfo1 dom_info_1
;
2735 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2744 NT_STATUS_NOT_OK_RETURN(status
);
2746 dom_info_1
.password_history_length
=
2747 info1005
->usrmod1005_password_hist_len
;
2749 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2757 /****************************************************************
2758 ****************************************************************/
2760 static NTSTATUS
set_USER_MODALS_INFO_buffer(TALLOC_CTX
*mem_ctx
,
2761 struct rpc_pipe_client
*pipe_cli
,
2763 struct policy_handle
*domain_handle
,
2764 struct dom_sid
*domain_sid
,
2767 struct USER_MODALS_INFO_0
*info0
;
2768 struct USER_MODALS_INFO_3
*info3
;
2769 struct USER_MODALS_INFO_1001
*info1001
;
2770 struct USER_MODALS_INFO_1002
*info1002
;
2771 struct USER_MODALS_INFO_1003
*info1003
;
2772 struct USER_MODALS_INFO_1004
*info1004
;
2773 struct USER_MODALS_INFO_1005
*info1005
;
2776 return ERROR_INSUFFICIENT_BUFFER
;
2781 info0
= (struct USER_MODALS_INFO_0
*)buffer
;
2782 return set_USER_MODALS_INFO_0_buffer(mem_ctx
,
2787 info3
= (struct USER_MODALS_INFO_3
*)buffer
;
2788 return set_USER_MODALS_INFO_3_buffer(mem_ctx
,
2793 info1001
= (struct USER_MODALS_INFO_1001
*)buffer
;
2794 return set_USER_MODALS_INFO_1001_buffer(mem_ctx
,
2799 info1002
= (struct USER_MODALS_INFO_1002
*)buffer
;
2800 return set_USER_MODALS_INFO_1002_buffer(mem_ctx
,
2805 info1003
= (struct USER_MODALS_INFO_1003
*)buffer
;
2806 return set_USER_MODALS_INFO_1003_buffer(mem_ctx
,
2811 info1004
= (struct USER_MODALS_INFO_1004
*)buffer
;
2812 return set_USER_MODALS_INFO_1004_buffer(mem_ctx
,
2817 info1005
= (struct USER_MODALS_INFO_1005
*)buffer
;
2818 return set_USER_MODALS_INFO_1005_buffer(mem_ctx
,
2827 return NT_STATUS_OK
;
2830 /****************************************************************
2831 ****************************************************************/
2833 WERROR
NetUserModalsSet_r(struct libnetapi_ctx
*ctx
,
2834 struct NetUserModalsSet
*r
)
2836 struct rpc_pipe_client
*pipe_cli
= NULL
;
2840 struct policy_handle connect_handle
, domain_handle
;
2841 struct dom_sid2
*domain_sid
= NULL
;
2842 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2844 ZERO_STRUCT(connect_handle
);
2845 ZERO_STRUCT(domain_handle
);
2847 if (!r
->in
.buffer
) {
2848 return WERR_INVALID_PARAM
;
2851 switch (r
->in
.level
) {
2853 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2854 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2855 SAMR_DOMAIN_ACCESS_SET_INFO_1
|
2856 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2863 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2864 SAMR_DOMAIN_ACCESS_SET_INFO_1
;
2867 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2868 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2874 werr
= WERR_NOT_SUPPORTED
;
2877 werr
= WERR_UNKNOWN_LEVEL
;
2881 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2882 &ndr_table_samr
.syntax_id
,
2884 if (!W_ERROR_IS_OK(werr
)) {
2888 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2889 SAMR_ACCESS_ENUM_DOMAINS
|
2890 SAMR_ACCESS_LOOKUP_DOMAIN
,
2895 if (!W_ERROR_IS_OK(werr
)) {
2899 status
= set_USER_MODALS_INFO_buffer(ctx
,
2905 if (!NT_STATUS_IS_OK(status
)) {
2906 werr
= ntstatus_to_werror(status
);
2911 if (ctx
->disable_policy_handle_cache
) {
2912 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2913 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2919 /****************************************************************
2920 ****************************************************************/
2922 WERROR
NetUserModalsSet_l(struct libnetapi_ctx
*ctx
,
2923 struct NetUserModalsSet
*r
)
2925 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsSet
);
2928 /****************************************************************
2929 ****************************************************************/
2931 NTSTATUS
add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
2933 const char *group_name
,
2934 uint32_t attributes
,
2936 uint32_t *num_entries
)
2938 struct GROUP_USERS_INFO_0 u0
;
2939 struct GROUP_USERS_INFO_1 u1
;
2944 u0
.grui0_name
= talloc_strdup(mem_ctx
, group_name
);
2945 NT_STATUS_HAVE_NO_MEMORY(u0
.grui0_name
);
2947 u0
.grui0_name
= NULL
;
2950 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_0
, u0
,
2951 (struct GROUP_USERS_INFO_0
**)buffer
, num_entries
);
2955 u1
.grui1_name
= talloc_strdup(mem_ctx
, group_name
);
2956 NT_STATUS_HAVE_NO_MEMORY(u1
.grui1_name
);
2958 u1
.grui1_name
= NULL
;
2961 u1
.grui1_attributes
= attributes
;
2963 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_1
, u1
,
2964 (struct GROUP_USERS_INFO_1
**)buffer
, num_entries
);
2967 return NT_STATUS_INVALID_INFO_CLASS
;
2970 return NT_STATUS_OK
;
2973 /****************************************************************
2974 ****************************************************************/
2976 WERROR
NetUserGetGroups_r(struct libnetapi_ctx
*ctx
,
2977 struct NetUserGetGroups
*r
)
2979 struct rpc_pipe_client
*pipe_cli
= NULL
;
2980 struct policy_handle connect_handle
, domain_handle
, user_handle
;
2981 struct lsa_String lsa_account_name
;
2982 struct dom_sid2
*domain_sid
= NULL
;
2983 struct samr_Ids user_rids
, name_types
;
2984 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
2985 struct lsa_Strings names
;
2986 struct samr_Ids types
;
2987 uint32_t *rids
= NULL
;
2990 uint32_t entries_read
= 0;
2992 NTSTATUS status
= NT_STATUS_OK
;
2993 NTSTATUS result
= NT_STATUS_OK
;
2995 struct dcerpc_binding_handle
*b
= NULL
;
2997 ZERO_STRUCT(connect_handle
);
2998 ZERO_STRUCT(domain_handle
);
3000 if (!r
->out
.buffer
) {
3001 return WERR_INVALID_PARAM
;
3004 *r
->out
.buffer
= NULL
;
3005 *r
->out
.entries_read
= 0;
3006 *r
->out
.total_entries
= 0;
3008 switch (r
->in
.level
) {
3013 return WERR_UNKNOWN_LEVEL
;
3016 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3017 &ndr_table_samr
.syntax_id
,
3019 if (!W_ERROR_IS_OK(werr
)) {
3023 b
= pipe_cli
->binding_handle
;
3025 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3026 SAMR_ACCESS_ENUM_DOMAINS
|
3027 SAMR_ACCESS_LOOKUP_DOMAIN
,
3028 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3032 if (!W_ERROR_IS_OK(werr
)) {
3036 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3038 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3045 if (!NT_STATUS_IS_OK(status
)) {
3046 werr
= ntstatus_to_werror(status
);
3049 if (!NT_STATUS_IS_OK(result
)) {
3050 werr
= ntstatus_to_werror(result
);
3053 if (user_rids
.count
!= 1) {
3054 werr
= WERR_BAD_NET_RESP
;
3057 if (name_types
.count
!= 1) {
3058 werr
= WERR_BAD_NET_RESP
;
3062 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3064 SAMR_USER_ACCESS_GET_GROUPS
,
3068 if (!NT_STATUS_IS_OK(status
)) {
3069 werr
= ntstatus_to_werror(status
);
3072 if (!NT_STATUS_IS_OK(result
)) {
3073 werr
= ntstatus_to_werror(result
);
3077 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3081 if (!NT_STATUS_IS_OK(status
)) {
3082 werr
= ntstatus_to_werror(status
);
3085 if (!NT_STATUS_IS_OK(result
)) {
3086 werr
= ntstatus_to_werror(result
);
3090 rids
= talloc_array(ctx
, uint32_t, rid_array
->count
);
3096 for (i
=0; i
< rid_array
->count
; i
++) {
3097 rids
[i
] = rid_array
->rids
[i
].rid
;
3100 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3107 if (!NT_STATUS_IS_OK(status
)) {
3108 werr
= ntstatus_to_werror(status
);
3111 if (!NT_STATUS_IS_OK(result
) &&
3112 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3113 werr
= ntstatus_to_werror(result
);
3117 for (i
=0; i
< names
.count
; i
++) {
3118 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
3120 names
.names
[i
].string
,
3121 rid_array
->rids
[i
].attributes
,
3124 if (!NT_STATUS_IS_OK(status
)) {
3125 werr
= ntstatus_to_werror(status
);
3130 *r
->out
.entries_read
= entries_read
;
3131 *r
->out
.total_entries
= entries_read
;
3134 if (ctx
->disable_policy_handle_cache
) {
3135 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3136 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3142 /****************************************************************
3143 ****************************************************************/
3145 WERROR
NetUserGetGroups_l(struct libnetapi_ctx
*ctx
,
3146 struct NetUserGetGroups
*r
)
3148 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetGroups
);
3151 /****************************************************************
3152 ****************************************************************/
3154 WERROR
NetUserSetGroups_r(struct libnetapi_ctx
*ctx
,
3155 struct NetUserSetGroups
*r
)
3157 struct rpc_pipe_client
*pipe_cli
= NULL
;
3158 struct policy_handle connect_handle
, domain_handle
, user_handle
, group_handle
;
3159 struct lsa_String lsa_account_name
;
3160 struct dom_sid2
*domain_sid
= NULL
;
3161 struct samr_Ids user_rids
, name_types
;
3162 struct samr_Ids group_rids
;
3163 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3164 struct lsa_String
*lsa_names
= NULL
;
3166 uint32_t *add_rids
= NULL
;
3167 uint32_t *del_rids
= NULL
;
3168 size_t num_add_rids
= 0;
3169 size_t num_del_rids
= 0;
3171 uint32_t *member_rids
= NULL
;
3172 size_t num_member_rids
= 0;
3174 struct GROUP_USERS_INFO_0
*i0
= NULL
;
3175 struct GROUP_USERS_INFO_1
*i1
= NULL
;
3179 NTSTATUS status
= NT_STATUS_OK
;
3180 NTSTATUS result
= NT_STATUS_OK
;
3182 struct dcerpc_binding_handle
*b
= NULL
;
3184 ZERO_STRUCT(connect_handle
);
3185 ZERO_STRUCT(domain_handle
);
3187 if (!r
->in
.buffer
) {
3188 return WERR_INVALID_PARAM
;
3191 switch (r
->in
.level
) {
3196 return WERR_UNKNOWN_LEVEL
;
3199 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3200 &ndr_table_samr
.syntax_id
,
3202 if (!W_ERROR_IS_OK(werr
)) {
3206 b
= pipe_cli
->binding_handle
;
3208 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3209 SAMR_ACCESS_ENUM_DOMAINS
|
3210 SAMR_ACCESS_LOOKUP_DOMAIN
,
3211 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3215 if (!W_ERROR_IS_OK(werr
)) {
3219 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3221 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3228 if (!NT_STATUS_IS_OK(status
)) {
3229 werr
= ntstatus_to_werror(status
);
3232 if (!NT_STATUS_IS_OK(result
)) {
3233 werr
= ntstatus_to_werror(result
);
3236 if (user_rids
.count
!= 1) {
3237 werr
= WERR_BAD_NET_RESP
;
3240 if (name_types
.count
!= 1) {
3241 werr
= WERR_BAD_NET_RESP
;
3245 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3247 SAMR_USER_ACCESS_GET_GROUPS
,
3251 if (!NT_STATUS_IS_OK(status
)) {
3252 werr
= ntstatus_to_werror(status
);
3255 if (!NT_STATUS_IS_OK(result
)) {
3256 werr
= ntstatus_to_werror(result
);
3260 switch (r
->in
.level
) {
3262 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
3265 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
3269 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
3275 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3277 switch (r
->in
.level
) {
3279 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
3283 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
3289 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3296 if (!NT_STATUS_IS_OK(status
)) {
3297 werr
= ntstatus_to_werror(status
);
3300 if (!NT_STATUS_IS_OK(result
)) {
3301 werr
= ntstatus_to_werror(result
);
3304 if (group_rids
.count
!= r
->in
.num_entries
) {
3305 werr
= WERR_BAD_NET_RESP
;
3308 if (name_types
.count
!= r
->in
.num_entries
) {
3309 werr
= WERR_BAD_NET_RESP
;
3313 member_rids
= group_rids
.ids
;
3314 num_member_rids
= group_rids
.count
;
3316 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3320 if (!NT_STATUS_IS_OK(status
)) {
3321 werr
= ntstatus_to_werror(status
);
3324 if (!NT_STATUS_IS_OK(result
)) {
3325 werr
= ntstatus_to_werror(result
);
3331 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3332 bool already_member
= false;
3333 for (k
=0; k
< rid_array
->count
; k
++) {
3334 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3335 already_member
= true;
3339 if (!already_member
) {
3340 if (!add_rid_to_array_unique(ctx
,
3342 &add_rids
, &num_add_rids
)) {
3343 werr
= WERR_GENERAL_FAILURE
;
3351 for (k
=0; k
< rid_array
->count
; k
++) {
3352 bool keep_member
= false;
3353 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3354 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3360 if (!add_rid_to_array_unique(ctx
,
3361 rid_array
->rids
[k
].rid
,
3362 &del_rids
, &num_del_rids
)) {
3363 werr
= WERR_GENERAL_FAILURE
;
3371 for (i
=0; i
< num_add_rids
; i
++) {
3372 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3374 SAMR_GROUP_ACCESS_ADD_MEMBER
,
3378 if (!NT_STATUS_IS_OK(status
)) {
3379 werr
= ntstatus_to_werror(status
);
3382 if (!NT_STATUS_IS_OK(result
)) {
3383 werr
= ntstatus_to_werror(result
);
3387 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
3392 if (!NT_STATUS_IS_OK(status
)) {
3393 werr
= ntstatus_to_werror(status
);
3396 if (!NT_STATUS_IS_OK(result
)) {
3397 werr
= ntstatus_to_werror(result
);
3401 if (is_valid_policy_hnd(&group_handle
)) {
3402 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3408 for (i
=0; i
< num_del_rids
; i
++) {
3409 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3411 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
3415 if (!NT_STATUS_IS_OK(status
)) {
3416 werr
= ntstatus_to_werror(status
);
3419 if (!NT_STATUS_IS_OK(result
)) {
3420 werr
= ntstatus_to_werror(result
);
3424 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
3428 if (!NT_STATUS_IS_OK(status
)) {
3429 werr
= ntstatus_to_werror(status
);
3432 if (!NT_STATUS_IS_OK(result
)) {
3433 werr
= ntstatus_to_werror(result
);
3437 if (is_valid_policy_hnd(&group_handle
)) {
3438 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3445 if (is_valid_policy_hnd(&group_handle
)) {
3446 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3449 if (ctx
->disable_policy_handle_cache
) {
3450 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3451 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3457 /****************************************************************
3458 ****************************************************************/
3460 WERROR
NetUserSetGroups_l(struct libnetapi_ctx
*ctx
,
3461 struct NetUserSetGroups
*r
)
3463 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetGroups
);
3466 /****************************************************************
3467 ****************************************************************/
3469 static NTSTATUS
add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
3471 const char *group_name
,
3473 uint32_t *num_entries
)
3475 struct LOCALGROUP_USERS_INFO_0 u0
;
3479 u0
.lgrui0_name
= talloc_strdup(mem_ctx
, group_name
);
3480 NT_STATUS_HAVE_NO_MEMORY(u0
.lgrui0_name
);
3482 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_USERS_INFO_0
, u0
,
3483 (struct LOCALGROUP_USERS_INFO_0
**)buffer
, num_entries
);
3486 return NT_STATUS_INVALID_INFO_CLASS
;
3489 return NT_STATUS_OK
;
3492 /****************************************************************
3493 ****************************************************************/
3495 WERROR
NetUserGetLocalGroups_r(struct libnetapi_ctx
*ctx
,
3496 struct NetUserGetLocalGroups
*r
)
3498 struct rpc_pipe_client
*pipe_cli
= NULL
;
3499 struct policy_handle connect_handle
, domain_handle
, user_handle
,
3501 struct lsa_String lsa_account_name
;
3502 struct dom_sid2
*domain_sid
= NULL
;
3503 struct samr_Ids user_rids
, name_types
;
3504 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3505 struct lsa_Strings names
;
3506 struct samr_Ids types
;
3507 uint32_t *rids
= NULL
;
3508 size_t num_rids
= 0;
3509 struct dom_sid user_sid
;
3510 struct lsa_SidArray sid_array
;
3511 struct samr_Ids domain_rids
;
3512 struct samr_Ids builtin_rids
;
3515 uint32_t entries_read
= 0;
3517 NTSTATUS status
= NT_STATUS_OK
;
3518 NTSTATUS result
= NT_STATUS_OK
;
3520 struct dcerpc_binding_handle
*b
= NULL
;
3522 ZERO_STRUCT(connect_handle
);
3523 ZERO_STRUCT(domain_handle
);
3525 if (!r
->out
.buffer
) {
3526 return WERR_INVALID_PARAM
;
3529 *r
->out
.buffer
= NULL
;
3530 *r
->out
.entries_read
= 0;
3531 *r
->out
.total_entries
= 0;
3533 switch (r
->in
.level
) {
3538 return WERR_UNKNOWN_LEVEL
;
3541 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3542 &ndr_table_samr
.syntax_id
,
3544 if (!W_ERROR_IS_OK(werr
)) {
3548 b
= pipe_cli
->binding_handle
;
3550 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3551 SAMR_ACCESS_ENUM_DOMAINS
|
3552 SAMR_ACCESS_LOOKUP_DOMAIN
,
3553 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3554 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3558 if (!W_ERROR_IS_OK(werr
)) {
3562 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
3563 SAMR_ACCESS_ENUM_DOMAINS
|
3564 SAMR_ACCESS_LOOKUP_DOMAIN
,
3565 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3566 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3569 if (!W_ERROR_IS_OK(werr
)) {
3573 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3575 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3582 if (!NT_STATUS_IS_OK(status
)) {
3583 werr
= ntstatus_to_werror(status
);
3586 if (!NT_STATUS_IS_OK(result
)) {
3587 werr
= ntstatus_to_werror(result
);
3590 if (user_rids
.count
!= 1) {
3591 werr
= WERR_BAD_NET_RESP
;
3594 if (name_types
.count
!= 1) {
3595 werr
= WERR_BAD_NET_RESP
;
3599 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3601 SAMR_USER_ACCESS_GET_GROUPS
,
3605 if (!NT_STATUS_IS_OK(status
)) {
3606 werr
= ntstatus_to_werror(status
);
3609 if (!NT_STATUS_IS_OK(result
)) {
3610 werr
= ntstatus_to_werror(result
);
3614 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3618 if (!NT_STATUS_IS_OK(status
)) {
3619 werr
= ntstatus_to_werror(status
);
3622 if (!NT_STATUS_IS_OK(result
)) {
3623 werr
= ntstatus_to_werror(result
);
3627 if (!sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0])) {
3632 sid_array
.num_sids
= rid_array
->count
+ 1;
3633 sid_array
.sids
= TALLOC_ARRAY(ctx
, struct lsa_SidPtr
, sid_array
.num_sids
);
3634 if (!sid_array
.sids
) {
3639 sid_array
.sids
[0].sid
= dom_sid_dup(ctx
, &user_sid
);
3640 if (!sid_array
.sids
[0].sid
) {
3645 for (i
=0; i
< rid_array
->count
; i
++) {
3648 if (!sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
)) {
3653 sid_array
.sids
[i
+1].sid
= dom_sid_dup(ctx
, &sid
);
3654 if (!sid_array
.sids
[i
+1].sid
) {
3660 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3665 if (!NT_STATUS_IS_OK(status
)) {
3666 werr
= ntstatus_to_werror(status
);
3669 if (!NT_STATUS_IS_OK(result
)) {
3670 werr
= ntstatus_to_werror(result
);
3674 for (i
=0; i
< domain_rids
.count
; i
++) {
3675 if (!add_rid_to_array_unique(ctx
, domain_rids
.ids
[i
],
3676 &rids
, &num_rids
)) {
3682 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3687 if (!NT_STATUS_IS_OK(status
)) {
3688 werr
= ntstatus_to_werror(status
);
3691 if (!NT_STATUS_IS_OK(result
)) {
3692 werr
= ntstatus_to_werror(result
);
3696 for (i
=0; i
< builtin_rids
.count
; i
++) {
3697 if (!add_rid_to_array_unique(ctx
, builtin_rids
.ids
[i
],
3698 &rids
, &num_rids
)) {
3704 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3711 if (!NT_STATUS_IS_OK(status
)) {
3712 werr
= ntstatus_to_werror(status
);
3715 if (!NT_STATUS_IS_OK(result
)) {
3716 werr
= ntstatus_to_werror(result
);
3720 for (i
=0; i
< names
.count
; i
++) {
3721 status
= add_LOCALGROUP_USERS_INFO_X_buffer(ctx
,
3723 names
.names
[i
].string
,
3726 if (!NT_STATUS_IS_OK(status
)) {
3727 werr
= ntstatus_to_werror(status
);
3732 *r
->out
.entries_read
= entries_read
;
3733 *r
->out
.total_entries
= entries_read
;
3736 if (ctx
->disable_policy_handle_cache
) {
3737 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3738 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3744 /****************************************************************
3745 ****************************************************************/
3747 WERROR
NetUserGetLocalGroups_l(struct libnetapi_ctx
*ctx
,
3748 struct NetUserGetLocalGroups
*r
)
3750 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetLocalGroups
);