2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "../librpc/gen_ndr/ndr_samr_c.h"
27 #include "rpc_client/init_samr.h"
28 #include "../libds/common/flags.h"
29 #include "rpc_client/init_lsa.h"
30 #include "../libcli/security/security.h"
31 #include "../libds/common/flag_mapping.h"
32 #include "rpc_client/cli_pipe.h"
34 /****************************************************************
35 ****************************************************************/
37 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X
*infoX
,
38 struct samr_UserInfo21
*info21
)
40 uint32_t fields_present
= 0;
41 struct samr_LogonHours zero_logon_hours
;
42 struct lsa_BinaryString zero_parameters
;
46 ZERO_STRUCT(zero_logon_hours
);
47 ZERO_STRUCT(zero_parameters
);
49 if (infoX
->usriX_flags
) {
50 fields_present
|= SAMR_FIELD_ACCT_FLAGS
;
52 if (infoX
->usriX_name
) {
53 fields_present
|= SAMR_FIELD_ACCOUNT_NAME
;
55 if (infoX
->usriX_password
) {
56 fields_present
|= SAMR_FIELD_NT_PASSWORD_PRESENT
;
58 if (infoX
->usriX_flags
) {
59 fields_present
|= SAMR_FIELD_ACCT_FLAGS
;
61 if (infoX
->usriX_home_dir
) {
62 fields_present
|= SAMR_FIELD_HOME_DIRECTORY
;
64 if (infoX
->usriX_script_path
) {
65 fields_present
|= SAMR_FIELD_LOGON_SCRIPT
;
67 if (infoX
->usriX_comment
) {
68 fields_present
|= SAMR_FIELD_DESCRIPTION
;
70 if (infoX
->usriX_password_age
) {
71 fields_present
|= SAMR_FIELD_FORCE_PWD_CHANGE
;
73 if (infoX
->usriX_full_name
) {
74 fields_present
|= SAMR_FIELD_FULL_NAME
;
76 if (infoX
->usriX_usr_comment
) {
77 fields_present
|= SAMR_FIELD_COMMENT
;
79 if (infoX
->usriX_profile
) {
80 fields_present
|= SAMR_FIELD_PROFILE_PATH
;
82 if (infoX
->usriX_home_dir_drive
) {
83 fields_present
|= SAMR_FIELD_HOME_DRIVE
;
85 if (infoX
->usriX_primary_group_id
) {
86 fields_present
|= SAMR_FIELD_PRIMARY_GID
;
88 if (infoX
->usriX_country_code
) {
89 fields_present
|= SAMR_FIELD_COUNTRY_CODE
;
91 if (infoX
->usriX_workstations
) {
92 fields_present
|= SAMR_FIELD_WORKSTATIONS
;
95 unix_to_nt_time_abs(&password_age
, infoX
->usriX_password_age
);
97 /* TODO: infoX->usriX_priv */
99 info21
->last_logon
= 0;
100 info21
->last_logoff
= 0;
101 info21
->last_password_change
= 0;
102 info21
->acct_expiry
= 0;
103 info21
->allow_password_change
= 0;
104 info21
->force_password_change
= 0;
105 info21
->account_name
.string
= infoX
->usriX_name
;
106 info21
->full_name
.string
= infoX
->usriX_full_name
;
107 info21
->home_directory
.string
= infoX
->usriX_home_dir
;
108 info21
->home_drive
.string
= infoX
->usriX_home_dir_drive
;
109 info21
->logon_script
.string
= infoX
->usriX_script_path
;
110 info21
->profile_path
.string
= infoX
->usriX_profile
;
111 info21
->description
.string
= infoX
->usriX_comment
;
112 info21
->workstations
.string
= infoX
->usriX_workstations
;
113 info21
->comment
.string
= infoX
->usriX_usr_comment
;
114 info21
->parameters
= zero_parameters
;
115 info21
->lm_owf_password
= zero_parameters
;
116 info21
->nt_owf_password
= zero_parameters
;
117 info21
->private_data
.string
= NULL
;
118 info21
->buf_count
= 0;
119 info21
->buffer
= NULL
;
120 info21
->rid
= infoX
->usriX_user_id
;
121 info21
->primary_gid
= infoX
->usriX_primary_group_id
;
122 info21
->acct_flags
= infoX
->usriX_flags
;
123 info21
->fields_present
= fields_present
;
124 info21
->logon_hours
= zero_logon_hours
;
125 info21
->bad_password_count
= infoX
->usriX_bad_pw_count
;
126 info21
->logon_count
= infoX
->usriX_num_logons
;
127 info21
->country_code
= infoX
->usriX_country_code
;
128 info21
->code_page
= infoX
->usriX_code_page
;
129 info21
->lm_password_set
= 0;
130 info21
->nt_password_set
= 0;
131 info21
->password_expired
= infoX
->usriX_password_expired
;
132 info21
->private_data_sensitive
= 0;
135 /****************************************************************
136 ****************************************************************/
138 static NTSTATUS
construct_USER_INFO_X(uint32_t level
,
140 struct USER_INFO_X
*uX
)
142 struct USER_INFO_0
*u0
= NULL
;
143 struct USER_INFO_1
*u1
= NULL
;
144 struct USER_INFO_2
*u2
= NULL
;
145 struct USER_INFO_3
*u3
= NULL
;
146 struct USER_INFO_1003
*u1003
= NULL
;
147 struct USER_INFO_1006
*u1006
= NULL
;
148 struct USER_INFO_1007
*u1007
= NULL
;
149 struct USER_INFO_1009
*u1009
= NULL
;
150 struct USER_INFO_1011
*u1011
= NULL
;
151 struct USER_INFO_1012
*u1012
= NULL
;
152 struct USER_INFO_1014
*u1014
= NULL
;
153 struct USER_INFO_1024
*u1024
= NULL
;
154 struct USER_INFO_1051
*u1051
= NULL
;
155 struct USER_INFO_1052
*u1052
= NULL
;
156 struct USER_INFO_1053
*u1053
= NULL
;
158 if (!buffer
|| !uX
) {
159 return NT_STATUS_INVALID_PARAMETER
;
166 u0
= (struct USER_INFO_0
*)buffer
;
167 uX
->usriX_name
= u0
->usri0_name
;
170 u1
= (struct USER_INFO_1
*)buffer
;
171 uX
->usriX_name
= u1
->usri1_name
;
172 uX
->usriX_password
= u1
->usri1_password
;
173 uX
->usriX_password_age
= u1
->usri1_password_age
;
174 uX
->usriX_priv
= u1
->usri1_priv
;
175 uX
->usriX_home_dir
= u1
->usri1_home_dir
;
176 uX
->usriX_comment
= u1
->usri1_comment
;
177 uX
->usriX_flags
= u1
->usri1_flags
;
178 uX
->usriX_script_path
= u1
->usri1_script_path
;
181 u2
= (struct USER_INFO_2
*)buffer
;
182 uX
->usriX_name
= u2
->usri2_name
;
183 uX
->usriX_password
= u2
->usri2_password
;
184 uX
->usriX_password_age
= u2
->usri2_password_age
;
185 uX
->usriX_priv
= u2
->usri2_priv
;
186 uX
->usriX_home_dir
= u2
->usri2_home_dir
;
187 uX
->usriX_comment
= u2
->usri2_comment
;
188 uX
->usriX_flags
= u2
->usri2_flags
;
189 uX
->usriX_script_path
= u2
->usri2_script_path
;
190 uX
->usriX_auth_flags
= u2
->usri2_auth_flags
;
191 uX
->usriX_full_name
= u2
->usri2_full_name
;
192 uX
->usriX_usr_comment
= u2
->usri2_usr_comment
;
193 uX
->usriX_parms
= u2
->usri2_parms
;
194 uX
->usriX_workstations
= u2
->usri2_workstations
;
195 uX
->usriX_last_logon
= u2
->usri2_last_logon
;
196 uX
->usriX_last_logoff
= u2
->usri2_last_logoff
;
197 uX
->usriX_acct_expires
= u2
->usri2_acct_expires
;
198 uX
->usriX_max_storage
= u2
->usri2_max_storage
;
199 uX
->usriX_units_per_week
= u2
->usri2_units_per_week
;
200 uX
->usriX_logon_hours
= u2
->usri2_logon_hours
;
201 uX
->usriX_bad_pw_count
= u2
->usri2_bad_pw_count
;
202 uX
->usriX_num_logons
= u2
->usri2_num_logons
;
203 uX
->usriX_logon_server
= u2
->usri2_logon_server
;
204 uX
->usriX_country_code
= u2
->usri2_country_code
;
205 uX
->usriX_code_page
= u2
->usri2_code_page
;
208 u3
= (struct USER_INFO_3
*)buffer
;
209 uX
->usriX_name
= u3
->usri3_name
;
210 uX
->usriX_password_age
= u3
->usri3_password_age
;
211 uX
->usriX_priv
= u3
->usri3_priv
;
212 uX
->usriX_home_dir
= u3
->usri3_home_dir
;
213 uX
->usriX_comment
= u3
->usri3_comment
;
214 uX
->usriX_flags
= u3
->usri3_flags
;
215 uX
->usriX_script_path
= u3
->usri3_script_path
;
216 uX
->usriX_auth_flags
= u3
->usri3_auth_flags
;
217 uX
->usriX_full_name
= u3
->usri3_full_name
;
218 uX
->usriX_usr_comment
= u3
->usri3_usr_comment
;
219 uX
->usriX_parms
= u3
->usri3_parms
;
220 uX
->usriX_workstations
= u3
->usri3_workstations
;
221 uX
->usriX_last_logon
= u3
->usri3_last_logon
;
222 uX
->usriX_last_logoff
= u3
->usri3_last_logoff
;
223 uX
->usriX_acct_expires
= u3
->usri3_acct_expires
;
224 uX
->usriX_max_storage
= u3
->usri3_max_storage
;
225 uX
->usriX_units_per_week
= u3
->usri3_units_per_week
;
226 uX
->usriX_logon_hours
= u3
->usri3_logon_hours
;
227 uX
->usriX_bad_pw_count
= u3
->usri3_bad_pw_count
;
228 uX
->usriX_num_logons
= u3
->usri3_num_logons
;
229 uX
->usriX_logon_server
= u3
->usri3_logon_server
;
230 uX
->usriX_country_code
= u3
->usri3_country_code
;
231 uX
->usriX_code_page
= u3
->usri3_code_page
;
232 uX
->usriX_user_id
= u3
->usri3_user_id
;
233 uX
->usriX_primary_group_id
= u3
->usri3_primary_group_id
;
234 uX
->usriX_profile
= u3
->usri3_profile
;
235 uX
->usriX_home_dir_drive
= u3
->usri3_home_dir_drive
;
236 uX
->usriX_password_expired
= u3
->usri3_password_expired
;
239 u1003
= (struct USER_INFO_1003
*)buffer
;
240 uX
->usriX_password
= u1003
->usri1003_password
;
243 u1006
= (struct USER_INFO_1006
*)buffer
;
244 uX
->usriX_home_dir
= u1006
->usri1006_home_dir
;
247 u1007
= (struct USER_INFO_1007
*)buffer
;
248 uX
->usriX_comment
= u1007
->usri1007_comment
;
251 u1009
= (struct USER_INFO_1009
*)buffer
;
252 uX
->usriX_script_path
= u1009
->usri1009_script_path
;
255 u1011
= (struct USER_INFO_1011
*)buffer
;
256 uX
->usriX_full_name
= u1011
->usri1011_full_name
;
259 u1012
= (struct USER_INFO_1012
*)buffer
;
260 uX
->usriX_usr_comment
= u1012
->usri1012_usr_comment
;
263 u1014
= (struct USER_INFO_1014
*)buffer
;
264 uX
->usriX_workstations
= u1014
->usri1014_workstations
;
267 u1024
= (struct USER_INFO_1024
*)buffer
;
268 uX
->usriX_country_code
= u1024
->usri1024_country_code
;
271 u1051
= (struct USER_INFO_1051
*)buffer
;
272 uX
->usriX_primary_group_id
= u1051
->usri1051_primary_group_id
;
275 u1052
= (struct USER_INFO_1052
*)buffer
;
276 uX
->usriX_profile
= u1052
->usri1052_profile
;
279 u1053
= (struct USER_INFO_1053
*)buffer
;
280 uX
->usriX_home_dir_drive
= u1053
->usri1053_home_dir_drive
;
284 return NT_STATUS_INVALID_INFO_CLASS
;
290 /****************************************************************
291 ****************************************************************/
293 static NTSTATUS
set_user_info_USER_INFO_X(TALLOC_CTX
*ctx
,
294 struct rpc_pipe_client
*pipe_cli
,
295 DATA_BLOB
*session_key
,
296 struct policy_handle
*user_handle
,
297 struct USER_INFO_X
*uX
)
299 union samr_UserInfo user_info
;
300 struct samr_UserInfo21 info21
;
301 NTSTATUS status
, result
;
302 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
305 return NT_STATUS_INVALID_PARAMETER
;
308 convert_USER_INFO_X_to_samr_user_info21(uX
, &info21
);
310 ZERO_STRUCT(user_info
);
312 if (uX
->usriX_password
) {
314 user_info
.info25
.info
= info21
;
316 init_samr_CryptPasswordEx(uX
->usriX_password
,
318 &user_info
.info25
.password
);
320 status
= dcerpc_samr_SetUserInfo2(b
, talloc_tos(),
325 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
)) {
327 user_info
.info23
.info
= info21
;
329 init_samr_CryptPassword(uX
->usriX_password
,
331 &user_info
.info23
.password
);
333 status
= dcerpc_samr_SetUserInfo2(b
, talloc_tos(),
338 if (!NT_STATUS_IS_OK(status
)) {
343 if (!NT_STATUS_IS_OK(status
)) {
348 user_info
.info21
= info21
;
350 status
= dcerpc_samr_SetUserInfo(b
, talloc_tos(),
355 if (!NT_STATUS_IS_OK(status
)) {
363 /****************************************************************
364 ****************************************************************/
366 WERROR
NetUserAdd_r(struct libnetapi_ctx
*ctx
,
367 struct NetUserAdd
*r
)
369 struct rpc_pipe_client
*pipe_cli
= NULL
;
370 NTSTATUS status
, result
;
372 struct policy_handle connect_handle
, domain_handle
, user_handle
;
373 struct lsa_String lsa_account_name
;
374 struct dom_sid2
*domain_sid
= NULL
;
375 union samr_UserInfo
*user_info
= NULL
;
376 struct samr_PwInfo pw_info
;
377 uint32_t access_granted
= 0;
379 struct USER_INFO_X uX
;
380 struct dcerpc_binding_handle
*b
= NULL
;
381 DATA_BLOB session_key
;
383 ZERO_STRUCT(connect_handle
);
384 ZERO_STRUCT(domain_handle
);
385 ZERO_STRUCT(user_handle
);
388 return WERR_INVALID_PARAM
;
391 switch (r
->in
.level
) {
398 werr
= WERR_NOT_SUPPORTED
;
402 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
403 &ndr_table_samr
.syntax_id
,
405 if (!W_ERROR_IS_OK(werr
)) {
409 b
= pipe_cli
->binding_handle
;
411 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
412 if (!NT_STATUS_IS_OK(status
)) {
413 werr
= ntstatus_to_werror(status
);
417 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
418 SAMR_ACCESS_ENUM_DOMAINS
|
419 SAMR_ACCESS_LOOKUP_DOMAIN
,
420 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
421 SAMR_DOMAIN_ACCESS_CREATE_USER
|
422 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
426 if (!W_ERROR_IS_OK(werr
)) {
430 init_lsa_String(&lsa_account_name
, uX
.usriX_name
);
432 status
= dcerpc_samr_CreateUser2(b
, talloc_tos(),
438 SAMR_USER_ACCESS_SET_PASSWORD
|
439 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
440 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
445 if (!NT_STATUS_IS_OK(status
)) {
446 werr
= ntstatus_to_werror(status
);
449 if (!NT_STATUS_IS_OK(result
)) {
450 werr
= ntstatus_to_werror(result
);
454 status
= dcerpc_samr_QueryUserInfo(b
, talloc_tos(),
459 if (!NT_STATUS_IS_OK(status
)) {
460 werr
= ntstatus_to_werror(status
);
463 if (!NT_STATUS_IS_OK(result
)) {
464 werr
= ntstatus_to_werror(result
);
468 if (!(user_info
->info16
.acct_flags
& ACB_NORMAL
)) {
469 werr
= WERR_INVALID_PARAM
;
473 status
= dcerpc_samr_GetUserPwInfo(b
, talloc_tos(),
477 if (!NT_STATUS_IS_OK(status
)) {
478 werr
= ntstatus_to_werror(status
);
481 if (!NT_STATUS_IS_OK(result
)) {
482 werr
= ntstatus_to_werror(result
);
486 status
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
487 if (!NT_STATUS_IS_OK(status
)) {
488 werr
= ntstatus_to_werror(status
);
492 uX
.usriX_flags
|= ACB_NORMAL
;
494 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
498 if (!NT_STATUS_IS_OK(status
)) {
499 werr
= ntstatus_to_werror(status
);
507 dcerpc_samr_DeleteUser(b
, talloc_tos(),
512 if (is_valid_policy_hnd(&user_handle
) && b
) {
513 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
516 if (ctx
->disable_policy_handle_cache
) {
517 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
518 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
524 /****************************************************************
525 ****************************************************************/
527 WERROR
NetUserAdd_l(struct libnetapi_ctx
*ctx
,
528 struct NetUserAdd
*r
)
530 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserAdd
);
533 /****************************************************************
534 ****************************************************************/
536 WERROR
NetUserDel_r(struct libnetapi_ctx
*ctx
,
537 struct NetUserDel
*r
)
539 struct rpc_pipe_client
*pipe_cli
= NULL
;
540 NTSTATUS status
, result
;
542 struct policy_handle connect_handle
, builtin_handle
, domain_handle
, user_handle
;
543 struct lsa_String lsa_account_name
;
544 struct samr_Ids user_rids
, name_types
;
545 struct dom_sid2
*domain_sid
= NULL
;
546 struct dom_sid2 user_sid
;
547 struct dcerpc_binding_handle
*b
= NULL
;
549 ZERO_STRUCT(connect_handle
);
550 ZERO_STRUCT(builtin_handle
);
551 ZERO_STRUCT(domain_handle
);
552 ZERO_STRUCT(user_handle
);
554 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
555 &ndr_table_samr
.syntax_id
,
558 if (!W_ERROR_IS_OK(werr
)) {
562 b
= pipe_cli
->binding_handle
;
564 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
565 SAMR_ACCESS_ENUM_DOMAINS
|
566 SAMR_ACCESS_LOOKUP_DOMAIN
,
567 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
571 if (!W_ERROR_IS_OK(werr
)) {
575 status
= dcerpc_samr_OpenDomain(b
, talloc_tos(),
577 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
578 discard_const_p(struct dom_sid
, &global_sid_Builtin
),
581 if (!NT_STATUS_IS_OK(status
)) {
582 werr
= ntstatus_to_werror(status
);
585 if (!NT_STATUS_IS_OK(result
)) {
586 werr
= ntstatus_to_werror(result
);
590 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
592 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
599 if (!NT_STATUS_IS_OK(status
)) {
600 werr
= ntstatus_to_werror(status
);
603 if (!NT_STATUS_IS_OK(result
)) {
604 werr
= ntstatus_to_werror(result
);
608 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
614 if (!NT_STATUS_IS_OK(status
)) {
615 werr
= ntstatus_to_werror(status
);
618 if (!NT_STATUS_IS_OK(result
)) {
619 werr
= ntstatus_to_werror(result
);
623 sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0]);
625 status
= dcerpc_samr_RemoveMemberFromForeignDomain(b
, talloc_tos(),
629 if (!NT_STATUS_IS_OK(status
)) {
630 werr
= ntstatus_to_werror(status
);
633 if (!NT_STATUS_IS_OK(result
)) {
634 werr
= ntstatus_to_werror(result
);
638 status
= dcerpc_samr_DeleteUser(b
, talloc_tos(),
641 if (!NT_STATUS_IS_OK(status
)) {
642 werr
= ntstatus_to_werror(status
);
645 if (!NT_STATUS_IS_OK(result
)) {
646 werr
= ntstatus_to_werror(result
);
653 if (is_valid_policy_hnd(&user_handle
)) {
654 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
657 if (ctx
->disable_policy_handle_cache
) {
658 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
659 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
660 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
666 /****************************************************************
667 ****************************************************************/
669 WERROR
NetUserDel_l(struct libnetapi_ctx
*ctx
,
670 struct NetUserDel
*r
)
672 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserDel
);
675 /****************************************************************
676 ****************************************************************/
678 static NTSTATUS
libnetapi_samr_lookup_user(TALLOC_CTX
*mem_ctx
,
679 struct rpc_pipe_client
*pipe_cli
,
680 struct policy_handle
*domain_handle
,
681 struct policy_handle
*builtin_handle
,
682 const char *user_name
,
683 const struct dom_sid
*domain_sid
,
686 struct samr_UserInfo21
**info21
,
687 struct sec_desc_buf
**sec_desc
,
688 uint32_t *auth_flag_p
)
690 NTSTATUS status
, result
;
692 struct policy_handle user_handle
;
693 union samr_UserInfo
*user_info
= NULL
;
694 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
695 uint32_t access_mask
= SEC_STD_READ_CONTROL
|
696 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
697 SAMR_USER_ACCESS_GET_NAME_ETC
;
698 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
700 ZERO_STRUCT(user_handle
);
706 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
707 SAMR_USER_ACCESS_GET_GROUPS
;
713 access_mask
|= SAMR_USER_ACCESS_GET_LOGONINFO
|
714 SAMR_USER_ACCESS_GET_GROUPS
|
715 SAMR_USER_ACCESS_GET_LOCALE
;
722 return NT_STATUS_INVALID_LEVEL
;
729 status
= dcerpc_samr_OpenUser(b
, mem_ctx
,
735 if (!NT_STATUS_IS_OK(status
)) {
738 if (!NT_STATUS_IS_OK(result
)) {
743 status
= dcerpc_samr_QueryUserInfo(b
, mem_ctx
,
748 if (!NT_STATUS_IS_OK(status
)) {
751 if (!NT_STATUS_IS_OK(result
)) {
756 status
= dcerpc_samr_QuerySecurity(b
, mem_ctx
,
761 if (!NT_STATUS_IS_OK(status
)) {
764 if (!NT_STATUS_IS_OK(result
)) {
769 if (access_mask
& SAMR_USER_ACCESS_GET_GROUPS
) {
771 struct lsa_SidArray sid_array
;
772 struct samr_Ids alias_rids
;
774 uint32_t auth_flag
= 0;
777 status
= dcerpc_samr_GetGroupsForUser(b
, mem_ctx
,
781 if (!NT_STATUS_IS_OK(status
)) {
784 if (!NT_STATUS_IS_OK(result
)) {
789 sid_array
.num_sids
= rid_array
->count
+ 1;
790 sid_array
.sids
= talloc_array(mem_ctx
, struct lsa_SidPtr
,
792 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
);
794 for (i
=0; i
<rid_array
->count
; i
++) {
795 sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
);
796 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
797 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
800 sid_compose(&sid
, domain_sid
, rid
);
801 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sid
);
802 NT_STATUS_HAVE_NO_MEMORY(sid_array
.sids
[i
].sid
);
804 status
= dcerpc_samr_GetAliasMembership(b
, mem_ctx
,
809 if (!NT_STATUS_IS_OK(status
)) {
812 if (!NT_STATUS_IS_OK(result
)) {
817 for (i
=0; i
<alias_rids
.count
; i
++) {
818 switch (alias_rids
.ids
[i
]) {
819 case 550: /* Print Operators */
820 auth_flag
|= AF_OP_PRINT
;
822 case 549: /* Server Operators */
823 auth_flag
|= AF_OP_SERVER
;
825 case 548: /* Account Operators */
826 auth_flag
|= AF_OP_ACCOUNTS
;
834 *auth_flag_p
= auth_flag
;
838 *info21
= &user_info
->info21
;
841 if (is_valid_policy_hnd(&user_handle
)) {
842 dcerpc_samr_Close(b
, mem_ctx
, &user_handle
, &result
);
848 /****************************************************************
849 ****************************************************************/
851 static uint32_t samr_rid_to_priv_level(uint32_t rid
)
854 case DOMAIN_RID_ADMINISTRATOR
:
855 return USER_PRIV_ADMIN
;
856 case DOMAIN_RID_GUEST
:
857 return USER_PRIV_GUEST
;
859 return USER_PRIV_USER
;
863 /****************************************************************
864 ****************************************************************/
866 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb
)
868 uint32_t fl
= UF_SCRIPT
; /* god knows why */
870 fl
|= ds_acb2uf(acb
);
875 /****************************************************************
876 ****************************************************************/
878 static NTSTATUS
info21_to_USER_INFO_1(TALLOC_CTX
*mem_ctx
,
879 const struct samr_UserInfo21
*i21
,
880 struct USER_INFO_1
*i
)
883 i
->usri1_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
884 NT_STATUS_HAVE_NO_MEMORY(i
->usri1_name
);
885 i
->usri1_password
= NULL
;
886 i
->usri1_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
887 i
->usri1_priv
= samr_rid_to_priv_level(i21
->rid
);
888 i
->usri1_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
889 i
->usri1_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
890 i
->usri1_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
891 i
->usri1_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
896 /****************************************************************
897 ****************************************************************/
899 static NTSTATUS
info21_to_USER_INFO_2(TALLOC_CTX
*mem_ctx
,
900 const struct samr_UserInfo21
*i21
,
902 struct USER_INFO_2
*i
)
906 i
->usri2_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
907 NT_STATUS_HAVE_NO_MEMORY(i
->usri2_name
);
908 i
->usri2_password
= NULL
;
909 i
->usri2_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
910 i
->usri2_priv
= samr_rid_to_priv_level(i21
->rid
);
911 i
->usri2_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
912 i
->usri2_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
913 i
->usri2_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
914 i
->usri2_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
915 i
->usri2_auth_flags
= auth_flag
;
916 i
->usri2_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
917 i
->usri2_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
918 i
->usri2_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
919 i
->usri2_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
920 i
->usri2_last_logon
= nt_time_to_unix(i21
->last_logon
);
921 i
->usri2_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
922 i
->usri2_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
923 i
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
924 i
->usri2_units_per_week
= i21
->logon_hours
.units_per_week
;
925 i
->usri2_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
926 i
->usri2_bad_pw_count
= i21
->bad_password_count
;
927 i
->usri2_num_logons
= i21
->logon_count
;
928 i
->usri2_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
929 i
->usri2_country_code
= i21
->country_code
;
930 i
->usri2_code_page
= i21
->code_page
;
935 /****************************************************************
936 ****************************************************************/
938 static NTSTATUS
info21_to_USER_INFO_3(TALLOC_CTX
*mem_ctx
,
939 const struct samr_UserInfo21
*i21
,
941 struct USER_INFO_3
*i
)
945 i
->usri3_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
946 NT_STATUS_HAVE_NO_MEMORY(i
->usri3_name
);
947 i
->usri3_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
948 i
->usri3_priv
= samr_rid_to_priv_level(i21
->rid
);
949 i
->usri3_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
950 i
->usri3_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
951 i
->usri3_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
952 i
->usri3_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
953 i
->usri3_auth_flags
= auth_flag
;
954 i
->usri3_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
955 i
->usri3_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
956 i
->usri3_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
957 i
->usri3_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
958 i
->usri3_last_logon
= nt_time_to_unix(i21
->last_logon
);
959 i
->usri3_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
960 i
->usri3_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
961 i
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
962 i
->usri3_units_per_week
= i21
->logon_hours
.units_per_week
;
963 i
->usri3_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
964 i
->usri3_bad_pw_count
= i21
->bad_password_count
;
965 i
->usri3_num_logons
= i21
->logon_count
;
966 i
->usri3_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
967 i
->usri3_country_code
= i21
->country_code
;
968 i
->usri3_code_page
= i21
->code_page
;
969 i
->usri3_user_id
= i21
->rid
;
970 i
->usri3_primary_group_id
= i21
->primary_gid
;
971 i
->usri3_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
972 i
->usri3_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
973 i
->usri3_password_expired
= i21
->password_expired
;
978 /****************************************************************
979 ****************************************************************/
981 static NTSTATUS
info21_to_USER_INFO_4(TALLOC_CTX
*mem_ctx
,
982 const struct samr_UserInfo21
*i21
,
984 struct dom_sid
*domain_sid
,
985 struct USER_INFO_4
*i
)
991 i
->usri4_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
992 NT_STATUS_HAVE_NO_MEMORY(i
->usri4_name
);
993 i
->usri4_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
994 i
->usri4_password
= NULL
;
995 i
->usri4_priv
= samr_rid_to_priv_level(i21
->rid
);
996 i
->usri4_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
997 i
->usri4_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
998 i
->usri4_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
999 i
->usri4_script_path
= talloc_strdup(mem_ctx
, i21
->logon_script
.string
);
1000 i
->usri4_auth_flags
= auth_flag
;
1001 i
->usri4_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1002 i
->usri4_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1003 i
->usri4_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1004 i
->usri4_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1005 i
->usri4_last_logon
= nt_time_to_unix(i21
->last_logon
);
1006 i
->usri4_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1007 i
->usri4_acct_expires
= nt_time_to_unix(i21
->acct_expiry
);
1008 i
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1009 i
->usri4_units_per_week
= i21
->logon_hours
.units_per_week
;
1010 i
->usri4_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1011 i
->usri4_bad_pw_count
= i21
->bad_password_count
;
1012 i
->usri4_num_logons
= i21
->logon_count
;
1013 i
->usri4_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1014 i
->usri4_country_code
= i21
->country_code
;
1015 i
->usri4_code_page
= i21
->code_page
;
1016 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1017 return NT_STATUS_NO_MEMORY
;
1019 i
->usri4_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1020 i
->usri4_primary_group_id
= i21
->primary_gid
;
1021 i
->usri4_profile
= talloc_strdup(mem_ctx
, i21
->profile_path
.string
);
1022 i
->usri4_home_dir_drive
= talloc_strdup(mem_ctx
, i21
->home_drive
.string
);
1023 i
->usri4_password_expired
= i21
->password_expired
;
1025 return NT_STATUS_OK
;
1028 /****************************************************************
1029 ****************************************************************/
1031 static NTSTATUS
info21_to_USER_INFO_10(TALLOC_CTX
*mem_ctx
,
1032 const struct samr_UserInfo21
*i21
,
1033 struct USER_INFO_10
*i
)
1037 i
->usri10_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1038 NT_STATUS_HAVE_NO_MEMORY(i
->usri10_name
);
1039 i
->usri10_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1040 i
->usri10_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1041 i
->usri10_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1043 return NT_STATUS_OK
;
1046 /****************************************************************
1047 ****************************************************************/
1049 static NTSTATUS
info21_to_USER_INFO_11(TALLOC_CTX
*mem_ctx
,
1050 const struct samr_UserInfo21
*i21
,
1052 struct USER_INFO_11
*i
)
1056 i
->usri11_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1057 NT_STATUS_HAVE_NO_MEMORY(i
->usri11_name
);
1058 i
->usri11_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1059 i
->usri11_usr_comment
= talloc_strdup(mem_ctx
, i21
->comment
.string
);
1060 i
->usri11_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1061 i
->usri11_priv
= samr_rid_to_priv_level(i21
->rid
);
1062 i
->usri11_auth_flags
= auth_flag
;
1063 i
->usri11_password_age
= time(NULL
) - nt_time_to_unix(i21
->last_password_change
);
1064 i
->usri11_home_dir
= talloc_strdup(mem_ctx
, i21
->home_directory
.string
);
1065 i
->usri11_parms
= talloc_strndup(mem_ctx
, (const char *)i21
->parameters
.array
, i21
->parameters
.size
/2);
1066 i
->usri11_last_logon
= nt_time_to_unix(i21
->last_logon
);
1067 i
->usri11_last_logoff
= nt_time_to_unix(i21
->last_logoff
);
1068 i
->usri11_bad_pw_count
= i21
->bad_password_count
;
1069 i
->usri11_num_logons
= i21
->logon_count
;
1070 i
->usri11_logon_server
= talloc_strdup(mem_ctx
, "\\\\*");
1071 i
->usri11_country_code
= i21
->country_code
;
1072 i
->usri11_workstations
= talloc_strdup(mem_ctx
, i21
->workstations
.string
);
1073 i
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
; /* FIXME */
1074 i
->usri11_units_per_week
= i21
->logon_hours
.units_per_week
;
1075 i
->usri11_logon_hours
= (uint8_t *)talloc_memdup(mem_ctx
, i21
->logon_hours
.bits
, 21);
1076 i
->usri11_code_page
= i21
->code_page
;
1078 return NT_STATUS_OK
;
1081 /****************************************************************
1082 ****************************************************************/
1084 static NTSTATUS
info21_to_USER_INFO_20(TALLOC_CTX
*mem_ctx
,
1085 const struct samr_UserInfo21
*i21
,
1086 struct USER_INFO_20
*i
)
1090 i
->usri20_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1091 NT_STATUS_HAVE_NO_MEMORY(i
->usri20_name
);
1092 i
->usri20_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1093 i
->usri20_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1094 i
->usri20_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1095 i
->usri20_user_id
= i21
->rid
;
1097 return NT_STATUS_OK
;
1100 /****************************************************************
1101 ****************************************************************/
1103 static NTSTATUS
info21_to_USER_INFO_23(TALLOC_CTX
*mem_ctx
,
1104 const struct samr_UserInfo21
*i21
,
1105 struct dom_sid
*domain_sid
,
1106 struct USER_INFO_23
*i
)
1112 i
->usri23_name
= talloc_strdup(mem_ctx
, i21
->account_name
.string
);
1113 NT_STATUS_HAVE_NO_MEMORY(i
->usri23_name
);
1114 i
->usri23_comment
= talloc_strdup(mem_ctx
, i21
->description
.string
);
1115 i
->usri23_full_name
= talloc_strdup(mem_ctx
, i21
->full_name
.string
);
1116 i
->usri23_flags
= samr_acb_flags_to_netapi_flags(i21
->acct_flags
);
1117 if (!sid_compose(&sid
, domain_sid
, i21
->rid
)) {
1118 return NT_STATUS_NO_MEMORY
;
1120 i
->usri23_user_sid
= (struct domsid
*)dom_sid_dup(mem_ctx
, &sid
);
1122 return NT_STATUS_OK
;
1125 /****************************************************************
1126 ****************************************************************/
1128 static NTSTATUS
libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX
*mem_ctx
,
1129 struct rpc_pipe_client
*pipe_cli
,
1130 struct dom_sid
*domain_sid
,
1131 struct policy_handle
*domain_handle
,
1132 struct policy_handle
*builtin_handle
,
1133 const char *user_name
,
1137 uint32_t *num_entries
)
1141 struct samr_UserInfo21
*info21
= NULL
;
1142 struct sec_desc_buf
*sec_desc
= NULL
;
1143 uint32_t auth_flag
= 0;
1145 struct USER_INFO_0 info0
;
1146 struct USER_INFO_1 info1
;
1147 struct USER_INFO_2 info2
;
1148 struct USER_INFO_3 info3
;
1149 struct USER_INFO_4 info4
;
1150 struct USER_INFO_10 info10
;
1151 struct USER_INFO_11 info11
;
1152 struct USER_INFO_20 info20
;
1153 struct USER_INFO_23 info23
;
1167 return NT_STATUS_INVALID_LEVEL
;
1171 info0
.usri0_name
= talloc_strdup(mem_ctx
, user_name
);
1172 NT_STATUS_HAVE_NO_MEMORY(info0
.usri0_name
);
1174 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_0
, info0
,
1175 (struct USER_INFO_0
**)buffer
, num_entries
);
1177 return NT_STATUS_OK
;
1180 status
= libnetapi_samr_lookup_user(mem_ctx
, pipe_cli
,
1191 if (!NT_STATUS_IS_OK(status
)) {
1197 /* already returned above */
1200 status
= info21_to_USER_INFO_1(mem_ctx
, info21
, &info1
);
1201 NT_STATUS_NOT_OK_RETURN(status
);
1203 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_1
, info1
,
1204 (struct USER_INFO_1
**)buffer
, num_entries
);
1208 status
= info21_to_USER_INFO_2(mem_ctx
, info21
, auth_flag
, &info2
);
1209 NT_STATUS_NOT_OK_RETURN(status
);
1211 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_2
, info2
,
1212 (struct USER_INFO_2
**)buffer
, num_entries
);
1216 status
= info21_to_USER_INFO_3(mem_ctx
, info21
, auth_flag
, &info3
);
1217 NT_STATUS_NOT_OK_RETURN(status
);
1219 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_3
, info3
,
1220 (struct USER_INFO_3
**)buffer
, num_entries
);
1224 status
= info21_to_USER_INFO_4(mem_ctx
, info21
, auth_flag
, domain_sid
, &info4
);
1225 NT_STATUS_NOT_OK_RETURN(status
);
1227 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_4
, info4
,
1228 (struct USER_INFO_4
**)buffer
, num_entries
);
1232 status
= info21_to_USER_INFO_10(mem_ctx
, info21
, &info10
);
1233 NT_STATUS_NOT_OK_RETURN(status
);
1235 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_10
, info10
,
1236 (struct USER_INFO_10
**)buffer
, num_entries
);
1240 status
= info21_to_USER_INFO_11(mem_ctx
, info21
, auth_flag
, &info11
);
1241 NT_STATUS_NOT_OK_RETURN(status
);
1243 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_11
, info11
,
1244 (struct USER_INFO_11
**)buffer
, num_entries
);
1248 status
= info21_to_USER_INFO_20(mem_ctx
, info21
, &info20
);
1249 NT_STATUS_NOT_OK_RETURN(status
);
1251 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_20
, info20
,
1252 (struct USER_INFO_20
**)buffer
, num_entries
);
1256 status
= info21_to_USER_INFO_23(mem_ctx
, info21
, domain_sid
, &info23
);
1257 NT_STATUS_NOT_OK_RETURN(status
);
1259 ADD_TO_ARRAY(mem_ctx
, struct USER_INFO_23
, info23
,
1260 (struct USER_INFO_23
**)buffer
, num_entries
);
1263 return NT_STATUS_INVALID_LEVEL
;
1270 /****************************************************************
1271 ****************************************************************/
1273 WERROR
NetUserEnum_r(struct libnetapi_ctx
*ctx
,
1274 struct NetUserEnum
*r
)
1276 struct rpc_pipe_client
*pipe_cli
= NULL
;
1277 struct policy_handle connect_handle
;
1278 struct dom_sid2
*domain_sid
= NULL
;
1279 struct policy_handle domain_handle
, builtin_handle
;
1280 struct samr_SamArray
*sam
= NULL
;
1281 uint32_t filter
= ACB_NORMAL
;
1283 uint32_t entries_read
= 0;
1285 NTSTATUS status
= NT_STATUS_OK
;
1286 NTSTATUS result
= NT_STATUS_OK
;
1288 struct dcerpc_binding_handle
*b
= NULL
;
1290 ZERO_STRUCT(connect_handle
);
1291 ZERO_STRUCT(domain_handle
);
1292 ZERO_STRUCT(builtin_handle
);
1294 if (!r
->out
.buffer
) {
1295 return WERR_INVALID_PARAM
;
1298 *r
->out
.buffer
= NULL
;
1299 *r
->out
.entries_read
= 0;
1301 switch (r
->in
.level
) {
1313 return WERR_UNKNOWN_LEVEL
;
1316 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1317 &ndr_table_samr
.syntax_id
,
1319 if (!W_ERROR_IS_OK(werr
)) {
1323 b
= pipe_cli
->binding_handle
;
1325 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1326 SAMR_ACCESS_ENUM_DOMAINS
|
1327 SAMR_ACCESS_LOOKUP_DOMAIN
,
1328 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1329 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1332 if (!W_ERROR_IS_OK(werr
)) {
1336 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1337 SAMR_ACCESS_ENUM_DOMAINS
|
1338 SAMR_ACCESS_LOOKUP_DOMAIN
,
1339 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1340 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1341 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1345 if (!W_ERROR_IS_OK(werr
)) {
1349 switch (r
->in
.filter
) {
1350 case FILTER_NORMAL_ACCOUNT
:
1351 filter
= ACB_NORMAL
;
1353 case FILTER_TEMP_DUPLICATE_ACCOUNT
:
1354 filter
= ACB_TEMPDUP
;
1356 case FILTER_INTERDOMAIN_TRUST_ACCOUNT
:
1357 filter
= ACB_DOMTRUST
;
1359 case FILTER_WORKSTATION_TRUST_ACCOUNT
:
1360 filter
= ACB_WSTRUST
;
1362 case FILTER_SERVER_TRUST_ACCOUNT
:
1363 filter
= ACB_SVRTRUST
;
1369 status
= dcerpc_samr_EnumDomainUsers(b
,
1372 r
->in
.resume_handle
,
1378 if (!NT_STATUS_IS_OK(status
)) {
1379 werr
= ntstatus_to_werror(status
);
1382 werr
= ntstatus_to_werror(result
);
1383 if (NT_STATUS_IS_ERR(result
)) {
1387 for (i
=0; i
< sam
->count
; i
++) {
1389 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1393 sam
->entries
[i
].name
.string
,
1394 sam
->entries
[i
].idx
,
1397 r
->out
.entries_read
);
1398 if (!NT_STATUS_IS_OK(status
)) {
1399 werr
= ntstatus_to_werror(status
);
1406 if (NT_STATUS_IS_OK(result
) ||
1407 NT_STATUS_IS_ERR(result
)) {
1409 if (ctx
->disable_policy_handle_cache
) {
1410 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1411 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
1412 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1419 /****************************************************************
1420 ****************************************************************/
1422 WERROR
NetUserEnum_l(struct libnetapi_ctx
*ctx
,
1423 struct NetUserEnum
*r
)
1425 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserEnum
);
1428 /****************************************************************
1429 ****************************************************************/
1431 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX
*mem_ctx
,
1432 struct samr_DispInfoGeneral
*info
,
1433 uint32_t *entries_read
,
1436 struct NET_DISPLAY_USER
*user
= NULL
;
1439 user
= talloc_zero_array(mem_ctx
,
1440 struct NET_DISPLAY_USER
,
1442 W_ERROR_HAVE_NO_MEMORY(user
);
1444 for (i
= 0; i
< info
->count
; i
++) {
1445 user
[i
].usri1_name
= talloc_strdup(mem_ctx
,
1446 info
->entries
[i
].account_name
.string
);
1447 user
[i
].usri1_comment
= talloc_strdup(mem_ctx
,
1448 info
->entries
[i
].description
.string
);
1449 user
[i
].usri1_flags
=
1450 info
->entries
[i
].acct_flags
;
1451 user
[i
].usri1_full_name
= talloc_strdup(mem_ctx
,
1452 info
->entries
[i
].full_name
.string
);
1453 user
[i
].usri1_user_id
=
1454 info
->entries
[i
].rid
;
1455 user
[i
].usri1_next_index
=
1456 info
->entries
[i
].idx
;
1458 if (!user
[i
].usri1_name
) {
1463 *buffer
= talloc_memdup(mem_ctx
, user
,
1464 sizeof(struct NET_DISPLAY_USER
) * info
->count
);
1465 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1467 *entries_read
= info
->count
;
1472 /****************************************************************
1473 ****************************************************************/
1475 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX
*mem_ctx
,
1476 struct samr_DispInfoFull
*info
,
1477 uint32_t *entries_read
,
1480 struct NET_DISPLAY_MACHINE
*machine
= NULL
;
1483 machine
= talloc_zero_array(mem_ctx
,
1484 struct NET_DISPLAY_MACHINE
,
1486 W_ERROR_HAVE_NO_MEMORY(machine
);
1488 for (i
= 0; i
< info
->count
; i
++) {
1489 machine
[i
].usri2_name
= talloc_strdup(mem_ctx
,
1490 info
->entries
[i
].account_name
.string
);
1491 machine
[i
].usri2_comment
= talloc_strdup(mem_ctx
,
1492 info
->entries
[i
].description
.string
);
1493 machine
[i
].usri2_flags
=
1494 info
->entries
[i
].acct_flags
;
1495 machine
[i
].usri2_user_id
=
1496 info
->entries
[i
].rid
;
1497 machine
[i
].usri2_next_index
=
1498 info
->entries
[i
].idx
;
1500 if (!machine
[i
].usri2_name
) {
1505 *buffer
= talloc_memdup(mem_ctx
, machine
,
1506 sizeof(struct NET_DISPLAY_MACHINE
) * info
->count
);
1507 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1509 *entries_read
= info
->count
;
1514 /****************************************************************
1515 ****************************************************************/
1517 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX
*mem_ctx
,
1518 struct samr_DispInfoFullGroups
*info
,
1519 uint32_t *entries_read
,
1522 struct NET_DISPLAY_GROUP
*group
= NULL
;
1525 group
= talloc_zero_array(mem_ctx
,
1526 struct NET_DISPLAY_GROUP
,
1528 W_ERROR_HAVE_NO_MEMORY(group
);
1530 for (i
= 0; i
< info
->count
; i
++) {
1531 group
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
1532 info
->entries
[i
].account_name
.string
);
1533 group
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
1534 info
->entries
[i
].description
.string
);
1535 group
[i
].grpi3_group_id
=
1536 info
->entries
[i
].rid
;
1537 group
[i
].grpi3_attributes
=
1538 info
->entries
[i
].acct_flags
;
1539 group
[i
].grpi3_next_index
=
1540 info
->entries
[i
].idx
;
1542 if (!group
[i
].grpi3_name
) {
1547 *buffer
= talloc_memdup(mem_ctx
, group
,
1548 sizeof(struct NET_DISPLAY_GROUP
) * info
->count
);
1549 W_ERROR_HAVE_NO_MEMORY(*buffer
);
1551 *entries_read
= info
->count
;
1557 /****************************************************************
1558 ****************************************************************/
1560 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX
*mem_ctx
,
1561 union samr_DispInfo
*info
,
1563 uint32_t *entries_read
,
1568 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx
,
1573 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx
,
1578 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx
,
1586 return WERR_UNKNOWN_LEVEL
;
1589 /****************************************************************
1590 ****************************************************************/
1592 WERROR
NetQueryDisplayInformation_r(struct libnetapi_ctx
*ctx
,
1593 struct NetQueryDisplayInformation
*r
)
1595 struct rpc_pipe_client
*pipe_cli
= NULL
;
1596 struct policy_handle connect_handle
;
1597 struct dom_sid2
*domain_sid
= NULL
;
1598 struct policy_handle domain_handle
;
1599 union samr_DispInfo info
;
1600 struct dcerpc_binding_handle
*b
= NULL
;
1602 uint32_t total_size
= 0;
1603 uint32_t returned_size
= 0;
1605 NTSTATUS status
= NT_STATUS_OK
;
1606 NTSTATUS result
= NT_STATUS_OK
;
1610 *r
->out
.entries_read
= 0;
1612 ZERO_STRUCT(connect_handle
);
1613 ZERO_STRUCT(domain_handle
);
1615 switch (r
->in
.level
) {
1621 return WERR_UNKNOWN_LEVEL
;
1624 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1625 &ndr_table_samr
.syntax_id
,
1627 if (!W_ERROR_IS_OK(werr
)) {
1631 b
= pipe_cli
->binding_handle
;
1633 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1634 SAMR_ACCESS_ENUM_DOMAINS
|
1635 SAMR_ACCESS_LOOKUP_DOMAIN
,
1636 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
1637 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
1638 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1642 if (!W_ERROR_IS_OK(werr
)) {
1646 status
= dcerpc_samr_QueryDisplayInfo2(b
,
1651 r
->in
.entries_requested
,
1657 if (!NT_STATUS_IS_OK(status
)) {
1658 werr
= ntstatus_to_werror(status
);
1661 werr
= ntstatus_to_werror(result
);
1662 if (NT_STATUS_IS_ERR(result
)) {
1666 werr_tmp
= convert_samr_dispinfo_to_NET_DISPLAY(ctx
, &info
,
1668 r
->out
.entries_read
,
1670 if (!W_ERROR_IS_OK(werr_tmp
)) {
1675 if (NT_STATUS_IS_OK(result
) ||
1676 NT_STATUS_IS_ERR(result
)) {
1678 if (ctx
->disable_policy_handle_cache
) {
1679 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1680 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1688 /****************************************************************
1689 ****************************************************************/
1692 WERROR
NetQueryDisplayInformation_l(struct libnetapi_ctx
*ctx
,
1693 struct NetQueryDisplayInformation
*r
)
1695 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetQueryDisplayInformation
);
1698 /****************************************************************
1699 ****************************************************************/
1701 WERROR
NetUserChangePassword_r(struct libnetapi_ctx
*ctx
,
1702 struct NetUserChangePassword
*r
)
1704 return WERR_NOT_SUPPORTED
;
1707 /****************************************************************
1708 ****************************************************************/
1710 WERROR
NetUserChangePassword_l(struct libnetapi_ctx
*ctx
,
1711 struct NetUserChangePassword
*r
)
1713 return WERR_NOT_SUPPORTED
;
1716 /****************************************************************
1717 ****************************************************************/
1719 WERROR
NetUserGetInfo_r(struct libnetapi_ctx
*ctx
,
1720 struct NetUserGetInfo
*r
)
1722 struct rpc_pipe_client
*pipe_cli
= NULL
;
1723 NTSTATUS status
, result
;
1726 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1727 struct lsa_String lsa_account_name
;
1728 struct dom_sid2
*domain_sid
= NULL
;
1729 struct samr_Ids user_rids
, name_types
;
1730 uint32_t num_entries
= 0;
1731 struct dcerpc_binding_handle
*b
= NULL
;
1733 ZERO_STRUCT(connect_handle
);
1734 ZERO_STRUCT(domain_handle
);
1735 ZERO_STRUCT(builtin_handle
);
1736 ZERO_STRUCT(user_handle
);
1738 if (!r
->out
.buffer
) {
1739 return WERR_INVALID_PARAM
;
1742 switch (r
->in
.level
) {
1754 werr
= WERR_UNKNOWN_LEVEL
;
1758 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1759 &ndr_table_samr
.syntax_id
,
1761 if (!W_ERROR_IS_OK(werr
)) {
1765 b
= pipe_cli
->binding_handle
;
1767 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1768 SAMR_ACCESS_ENUM_DOMAINS
|
1769 SAMR_ACCESS_LOOKUP_DOMAIN
,
1770 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1774 if (!W_ERROR_IS_OK(werr
)) {
1778 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1779 SAMR_ACCESS_ENUM_DOMAINS
|
1780 SAMR_ACCESS_LOOKUP_DOMAIN
,
1781 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1782 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1785 if (!W_ERROR_IS_OK(werr
)) {
1789 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1791 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1798 if (!NT_STATUS_IS_OK(status
)) {
1799 werr
= ntstatus_to_werror(status
);
1802 if (!NT_STATUS_IS_OK(result
)) {
1803 werr
= ntstatus_to_werror(result
);
1807 status
= libnetapi_samr_lookup_user_map_USER_INFO(ctx
, pipe_cli
,
1816 if (!NT_STATUS_IS_OK(status
)) {
1817 werr
= ntstatus_to_werror(status
);
1822 if (is_valid_policy_hnd(&user_handle
) && b
) {
1823 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
1826 if (ctx
->disable_policy_handle_cache
) {
1827 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
1828 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
1834 /****************************************************************
1835 ****************************************************************/
1837 WERROR
NetUserGetInfo_l(struct libnetapi_ctx
*ctx
,
1838 struct NetUserGetInfo
*r
)
1840 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetInfo
);
1843 /****************************************************************
1844 ****************************************************************/
1846 WERROR
NetUserSetInfo_r(struct libnetapi_ctx
*ctx
,
1847 struct NetUserSetInfo
*r
)
1849 struct rpc_pipe_client
*pipe_cli
= NULL
;
1850 NTSTATUS status
, result
;
1853 struct policy_handle connect_handle
, domain_handle
, builtin_handle
, user_handle
;
1854 struct lsa_String lsa_account_name
;
1855 struct dom_sid2
*domain_sid
= NULL
;
1856 struct samr_Ids user_rids
, name_types
;
1857 uint32_t user_mask
= 0;
1859 struct USER_INFO_X uX
;
1860 struct dcerpc_binding_handle
*b
= NULL
;
1861 DATA_BLOB session_key
;
1863 ZERO_STRUCT(connect_handle
);
1864 ZERO_STRUCT(domain_handle
);
1865 ZERO_STRUCT(builtin_handle
);
1866 ZERO_STRUCT(user_handle
);
1868 if (!r
->in
.buffer
) {
1869 return WERR_INVALID_PARAM
;
1872 switch (r
->in
.level
) {
1874 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1877 user_mask
= SAMR_USER_ACCESS_SET_PASSWORD
;
1886 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
;
1890 user_mask
= SAMR_USER_ACCESS_SET_LOC_COM
;
1893 user_mask
= SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1894 SAMR_USER_ACCESS_GET_GROUPS
;
1897 user_mask
= SEC_STD_READ_CONTROL
|
1899 SAMR_USER_ACCESS_GET_GROUPS
|
1900 SAMR_USER_ACCESS_SET_PASSWORD
|
1901 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
1902 SAMR_USER_ACCESS_GET_ATTRIBUTES
|
1903 SAMR_USER_ACCESS_SET_LOC_COM
;
1915 werr
= WERR_NOT_SUPPORTED
;
1918 werr
= WERR_UNKNOWN_LEVEL
;
1922 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
1923 &ndr_table_samr
.syntax_id
,
1925 if (!W_ERROR_IS_OK(werr
)) {
1929 b
= pipe_cli
->binding_handle
;
1931 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
1932 SAMR_ACCESS_ENUM_DOMAINS
|
1933 SAMR_ACCESS_LOOKUP_DOMAIN
,
1934 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
1935 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
1939 if (!W_ERROR_IS_OK(werr
)) {
1943 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
1944 SAMR_ACCESS_ENUM_DOMAINS
|
1945 SAMR_ACCESS_LOOKUP_DOMAIN
,
1946 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
1947 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
1950 if (!W_ERROR_IS_OK(werr
)) {
1954 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
1956 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
1963 if (!NT_STATUS_IS_OK(status
)) {
1964 werr
= ntstatus_to_werror(status
);
1967 if (!NT_STATUS_IS_OK(result
)) {
1968 werr
= ntstatus_to_werror(result
);
1972 status
= dcerpc_samr_OpenUser(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
);
1987 status
= construct_USER_INFO_X(r
->in
.level
, r
->in
.buffer
, &uX
);
1988 if (!NT_STATUS_IS_OK(status
)) {
1989 werr
= ntstatus_to_werror(status
);
1993 status
= cli_get_session_key(talloc_tos(), pipe_cli
, &session_key
);
1994 if (!NT_STATUS_IS_OK(status
)) {
1995 werr
= ntstatus_to_werror(status
);
1999 status
= set_user_info_USER_INFO_X(ctx
, pipe_cli
,
2003 if (!NT_STATUS_IS_OK(status
)) {
2004 werr
= ntstatus_to_werror(status
);
2011 if (is_valid_policy_hnd(&user_handle
) && b
) {
2012 dcerpc_samr_Close(b
, talloc_tos(), &user_handle
, &result
);
2015 if (ctx
->disable_policy_handle_cache
) {
2016 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2017 libnetapi_samr_close_builtin_handle(ctx
, &builtin_handle
);
2018 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2024 /****************************************************************
2025 ****************************************************************/
2027 WERROR
NetUserSetInfo_l(struct libnetapi_ctx
*ctx
,
2028 struct NetUserSetInfo
*r
)
2030 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetInfo
);
2033 /****************************************************************
2034 ****************************************************************/
2036 static NTSTATUS
query_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2037 struct rpc_pipe_client
*pipe_cli
,
2038 struct policy_handle
*domain_handle
,
2039 struct samr_DomInfo1
*info1
,
2040 struct samr_DomInfo3
*info3
,
2041 struct samr_DomInfo5
*info5
,
2042 struct samr_DomInfo6
*info6
,
2043 struct samr_DomInfo7
*info7
,
2044 struct samr_DomInfo12
*info12
)
2046 NTSTATUS status
, result
;
2047 union samr_DomainInfo
*dom_info
= NULL
;
2048 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2051 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2056 NT_STATUS_NOT_OK_RETURN(status
);
2057 NT_STATUS_NOT_OK_RETURN(result
);
2059 *info1
= dom_info
->info1
;
2063 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2068 NT_STATUS_NOT_OK_RETURN(status
);
2069 NT_STATUS_NOT_OK_RETURN(result
);
2071 *info3
= dom_info
->info3
;
2075 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2080 NT_STATUS_NOT_OK_RETURN(status
);
2081 NT_STATUS_NOT_OK_RETURN(result
);
2083 *info5
= dom_info
->info5
;
2087 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2092 NT_STATUS_NOT_OK_RETURN(status
);
2093 NT_STATUS_NOT_OK_RETURN(result
);
2095 *info6
= dom_info
->info6
;
2099 status
= dcerpc_samr_QueryDomainInfo(b
, mem_ctx
,
2104 NT_STATUS_NOT_OK_RETURN(status
);
2105 NT_STATUS_NOT_OK_RETURN(result
);
2107 *info7
= dom_info
->info7
;
2111 status
= dcerpc_samr_QueryDomainInfo2(b
, mem_ctx
,
2116 NT_STATUS_NOT_OK_RETURN(status
);
2117 NT_STATUS_NOT_OK_RETURN(result
);
2119 *info12
= dom_info
->info12
;
2122 return NT_STATUS_OK
;
2125 /****************************************************************
2126 ****************************************************************/
2128 static NTSTATUS
query_USER_MODALS_INFO_0(TALLOC_CTX
*mem_ctx
,
2129 struct rpc_pipe_client
*pipe_cli
,
2130 struct policy_handle
*domain_handle
,
2131 struct USER_MODALS_INFO_0
*info0
)
2134 struct samr_DomInfo1 dom_info1
;
2135 struct samr_DomInfo3 dom_info3
;
2137 ZERO_STRUCTP(info0
);
2139 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2148 NT_STATUS_NOT_OK_RETURN(status
);
2150 info0
->usrmod0_min_passwd_len
=
2151 dom_info1
.min_password_length
;
2152 info0
->usrmod0_max_passwd_age
=
2153 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.max_password_age
);
2154 info0
->usrmod0_min_passwd_age
=
2155 nt_time_to_unix_abs((NTTIME
*)&dom_info1
.min_password_age
);
2156 info0
->usrmod0_password_hist_len
=
2157 dom_info1
.password_history_length
;
2159 info0
->usrmod0_force_logoff
=
2160 nt_time_to_unix_abs(&dom_info3
.force_logoff_time
);
2162 return NT_STATUS_OK
;
2165 /****************************************************************
2166 ****************************************************************/
2168 static NTSTATUS
query_USER_MODALS_INFO_1(TALLOC_CTX
*mem_ctx
,
2169 struct rpc_pipe_client
*pipe_cli
,
2170 struct policy_handle
*domain_handle
,
2171 struct USER_MODALS_INFO_1
*info1
)
2174 struct samr_DomInfo6 dom_info6
;
2175 struct samr_DomInfo7 dom_info7
;
2177 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2186 NT_STATUS_NOT_OK_RETURN(status
);
2188 info1
->usrmod1_primary
=
2189 talloc_strdup(mem_ctx
, dom_info6
.primary
.string
);
2191 info1
->usrmod1_role
= dom_info7
.role
;
2193 return NT_STATUS_OK
;
2196 /****************************************************************
2197 ****************************************************************/
2199 static NTSTATUS
query_USER_MODALS_INFO_2(TALLOC_CTX
*mem_ctx
,
2200 struct rpc_pipe_client
*pipe_cli
,
2201 struct policy_handle
*domain_handle
,
2202 struct dom_sid
*domain_sid
,
2203 struct USER_MODALS_INFO_2
*info2
)
2206 struct samr_DomInfo5 dom_info5
;
2208 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2217 NT_STATUS_NOT_OK_RETURN(status
);
2219 info2
->usrmod2_domain_name
=
2220 talloc_strdup(mem_ctx
, dom_info5
.domain_name
.string
);
2221 info2
->usrmod2_domain_id
=
2222 (struct domsid
*)dom_sid_dup(mem_ctx
, domain_sid
);
2224 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_name
);
2225 NT_STATUS_HAVE_NO_MEMORY(info2
->usrmod2_domain_id
);
2227 return NT_STATUS_OK
;
2230 /****************************************************************
2231 ****************************************************************/
2233 static NTSTATUS
query_USER_MODALS_INFO_3(TALLOC_CTX
*mem_ctx
,
2234 struct rpc_pipe_client
*pipe_cli
,
2235 struct policy_handle
*domain_handle
,
2236 struct USER_MODALS_INFO_3
*info3
)
2239 struct samr_DomInfo12 dom_info12
;
2241 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2250 NT_STATUS_NOT_OK_RETURN(status
);
2252 info3
->usrmod3_lockout_duration
=
2253 nt_time_to_unix_abs(&dom_info12
.lockout_duration
);
2254 info3
->usrmod3_lockout_observation_window
=
2255 nt_time_to_unix_abs(&dom_info12
.lockout_window
);
2256 info3
->usrmod3_lockout_threshold
=
2257 dom_info12
.lockout_threshold
;
2259 return NT_STATUS_OK
;
2262 /****************************************************************
2263 ****************************************************************/
2265 static NTSTATUS
query_USER_MODALS_INFO_to_buffer(TALLOC_CTX
*mem_ctx
,
2266 struct rpc_pipe_client
*pipe_cli
,
2268 struct policy_handle
*domain_handle
,
2269 struct dom_sid
*domain_sid
,
2274 struct USER_MODALS_INFO_0 info0
;
2275 struct USER_MODALS_INFO_1 info1
;
2276 struct USER_MODALS_INFO_2 info2
;
2277 struct USER_MODALS_INFO_3 info3
;
2280 return ERROR_INSUFFICIENT_BUFFER
;
2285 status
= query_USER_MODALS_INFO_0(mem_ctx
,
2289 NT_STATUS_NOT_OK_RETURN(status
);
2291 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info0
,
2296 status
= query_USER_MODALS_INFO_1(mem_ctx
,
2300 NT_STATUS_NOT_OK_RETURN(status
);
2302 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info1
,
2306 status
= query_USER_MODALS_INFO_2(mem_ctx
,
2311 NT_STATUS_NOT_OK_RETURN(status
);
2313 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info2
,
2317 status
= query_USER_MODALS_INFO_3(mem_ctx
,
2321 NT_STATUS_NOT_OK_RETURN(status
);
2323 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, &info3
,
2330 NT_STATUS_HAVE_NO_MEMORY(*buffer
);
2332 return NT_STATUS_OK
;
2335 /****************************************************************
2336 ****************************************************************/
2338 WERROR
NetUserModalsGet_r(struct libnetapi_ctx
*ctx
,
2339 struct NetUserModalsGet
*r
)
2341 struct rpc_pipe_client
*pipe_cli
= NULL
;
2345 struct policy_handle connect_handle
, domain_handle
;
2346 struct dom_sid2
*domain_sid
= NULL
;
2347 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2349 ZERO_STRUCT(connect_handle
);
2350 ZERO_STRUCT(domain_handle
);
2352 if (!r
->out
.buffer
) {
2353 return WERR_INVALID_PARAM
;
2356 switch (r
->in
.level
) {
2358 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2359 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2363 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
;
2366 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
;
2369 werr
= WERR_UNKNOWN_LEVEL
;
2373 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2374 &ndr_table_samr
.syntax_id
,
2376 if (!W_ERROR_IS_OK(werr
)) {
2380 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2381 SAMR_ACCESS_ENUM_DOMAINS
|
2382 SAMR_ACCESS_LOOKUP_DOMAIN
,
2387 if (!W_ERROR_IS_OK(werr
)) {
2394 /* 3: 12 (DomainInfo2) */
2396 status
= query_USER_MODALS_INFO_to_buffer(ctx
,
2402 if (!NT_STATUS_IS_OK(status
)) {
2403 werr
= ntstatus_to_werror(status
);
2408 if (ctx
->disable_policy_handle_cache
) {
2409 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2410 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2416 /****************************************************************
2417 ****************************************************************/
2419 WERROR
NetUserModalsGet_l(struct libnetapi_ctx
*ctx
,
2420 struct NetUserModalsGet
*r
)
2422 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsGet
);
2425 /****************************************************************
2426 ****************************************************************/
2428 static NTSTATUS
set_USER_MODALS_INFO_rpc(TALLOC_CTX
*mem_ctx
,
2429 struct rpc_pipe_client
*pipe_cli
,
2430 struct policy_handle
*domain_handle
,
2431 struct samr_DomInfo1
*info1
,
2432 struct samr_DomInfo3
*info3
,
2433 struct samr_DomInfo12
*info12
)
2435 NTSTATUS status
, result
;
2436 union samr_DomainInfo dom_info
;
2437 struct dcerpc_binding_handle
*b
= pipe_cli
->binding_handle
;
2441 ZERO_STRUCT(dom_info
);
2443 dom_info
.info1
= *info1
;
2445 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2450 NT_STATUS_NOT_OK_RETURN(status
);
2451 NT_STATUS_NOT_OK_RETURN(result
);
2456 ZERO_STRUCT(dom_info
);
2458 dom_info
.info3
= *info3
;
2460 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2466 NT_STATUS_NOT_OK_RETURN(status
);
2467 NT_STATUS_NOT_OK_RETURN(result
);
2472 ZERO_STRUCT(dom_info
);
2474 dom_info
.info12
= *info12
;
2476 status
= dcerpc_samr_SetDomainInfo(b
, mem_ctx
,
2482 NT_STATUS_NOT_OK_RETURN(status
);
2483 NT_STATUS_NOT_OK_RETURN(result
);
2486 return NT_STATUS_OK
;
2489 /****************************************************************
2490 ****************************************************************/
2492 static NTSTATUS
set_USER_MODALS_INFO_0_buffer(TALLOC_CTX
*mem_ctx
,
2493 struct rpc_pipe_client
*pipe_cli
,
2494 struct policy_handle
*domain_handle
,
2495 struct USER_MODALS_INFO_0
*info0
)
2498 struct samr_DomInfo1 dom_info_1
;
2499 struct samr_DomInfo3 dom_info_3
;
2501 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2510 NT_STATUS_NOT_OK_RETURN(status
);
2512 dom_info_1
.min_password_length
=
2513 info0
->usrmod0_min_passwd_len
;
2514 dom_info_1
.password_history_length
=
2515 info0
->usrmod0_password_hist_len
;
2517 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2518 info0
->usrmod0_max_passwd_age
);
2519 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2520 info0
->usrmod0_min_passwd_age
);
2522 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2523 info0
->usrmod0_force_logoff
);
2525 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2533 /****************************************************************
2534 ****************************************************************/
2536 static NTSTATUS
set_USER_MODALS_INFO_3_buffer(TALLOC_CTX
*mem_ctx
,
2537 struct rpc_pipe_client
*pipe_cli
,
2538 struct policy_handle
*domain_handle
,
2539 struct USER_MODALS_INFO_3
*info3
)
2542 struct samr_DomInfo12 dom_info_12
;
2544 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2553 NT_STATUS_NOT_OK_RETURN(status
);
2555 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_duration
,
2556 info3
->usrmod3_lockout_duration
);
2557 unix_to_nt_time_abs((NTTIME
*)&dom_info_12
.lockout_window
,
2558 info3
->usrmod3_lockout_observation_window
);
2559 dom_info_12
.lockout_threshold
= info3
->usrmod3_lockout_threshold
;
2561 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2569 /****************************************************************
2570 ****************************************************************/
2572 static NTSTATUS
set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX
*mem_ctx
,
2573 struct rpc_pipe_client
*pipe_cli
,
2574 struct policy_handle
*domain_handle
,
2575 struct USER_MODALS_INFO_1001
*info1001
)
2578 struct samr_DomInfo1 dom_info_1
;
2580 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2589 NT_STATUS_NOT_OK_RETURN(status
);
2591 dom_info_1
.min_password_length
=
2592 info1001
->usrmod1001_min_passwd_len
;
2594 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2602 /****************************************************************
2603 ****************************************************************/
2605 static NTSTATUS
set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX
*mem_ctx
,
2606 struct rpc_pipe_client
*pipe_cli
,
2607 struct policy_handle
*domain_handle
,
2608 struct USER_MODALS_INFO_1002
*info1002
)
2611 struct samr_DomInfo1 dom_info_1
;
2613 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2622 NT_STATUS_NOT_OK_RETURN(status
);
2624 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.max_password_age
,
2625 info1002
->usrmod1002_max_passwd_age
);
2627 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2635 /****************************************************************
2636 ****************************************************************/
2638 static NTSTATUS
set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX
*mem_ctx
,
2639 struct rpc_pipe_client
*pipe_cli
,
2640 struct policy_handle
*domain_handle
,
2641 struct USER_MODALS_INFO_1003
*info1003
)
2644 struct samr_DomInfo1 dom_info_1
;
2646 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2655 NT_STATUS_NOT_OK_RETURN(status
);
2657 unix_to_nt_time_abs((NTTIME
*)&dom_info_1
.min_password_age
,
2658 info1003
->usrmod1003_min_passwd_age
);
2660 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2668 /****************************************************************
2669 ****************************************************************/
2671 static NTSTATUS
set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX
*mem_ctx
,
2672 struct rpc_pipe_client
*pipe_cli
,
2673 struct policy_handle
*domain_handle
,
2674 struct USER_MODALS_INFO_1004
*info1004
)
2677 struct samr_DomInfo3 dom_info_3
;
2679 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2688 NT_STATUS_NOT_OK_RETURN(status
);
2690 unix_to_nt_time_abs(&dom_info_3
.force_logoff_time
,
2691 info1004
->usrmod1004_force_logoff
);
2693 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2701 /****************************************************************
2702 ****************************************************************/
2704 static NTSTATUS
set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX
*mem_ctx
,
2705 struct rpc_pipe_client
*pipe_cli
,
2706 struct policy_handle
*domain_handle
,
2707 struct USER_MODALS_INFO_1005
*info1005
)
2710 struct samr_DomInfo1 dom_info_1
;
2712 status
= query_USER_MODALS_INFO_rpc(mem_ctx
,
2721 NT_STATUS_NOT_OK_RETURN(status
);
2723 dom_info_1
.password_history_length
=
2724 info1005
->usrmod1005_password_hist_len
;
2726 return set_USER_MODALS_INFO_rpc(mem_ctx
,
2734 /****************************************************************
2735 ****************************************************************/
2737 static NTSTATUS
set_USER_MODALS_INFO_buffer(TALLOC_CTX
*mem_ctx
,
2738 struct rpc_pipe_client
*pipe_cli
,
2740 struct policy_handle
*domain_handle
,
2741 struct dom_sid
*domain_sid
,
2744 struct USER_MODALS_INFO_0
*info0
;
2745 struct USER_MODALS_INFO_3
*info3
;
2746 struct USER_MODALS_INFO_1001
*info1001
;
2747 struct USER_MODALS_INFO_1002
*info1002
;
2748 struct USER_MODALS_INFO_1003
*info1003
;
2749 struct USER_MODALS_INFO_1004
*info1004
;
2750 struct USER_MODALS_INFO_1005
*info1005
;
2753 return ERROR_INSUFFICIENT_BUFFER
;
2758 info0
= (struct USER_MODALS_INFO_0
*)buffer
;
2759 return set_USER_MODALS_INFO_0_buffer(mem_ctx
,
2764 info3
= (struct USER_MODALS_INFO_3
*)buffer
;
2765 return set_USER_MODALS_INFO_3_buffer(mem_ctx
,
2770 info1001
= (struct USER_MODALS_INFO_1001
*)buffer
;
2771 return set_USER_MODALS_INFO_1001_buffer(mem_ctx
,
2776 info1002
= (struct USER_MODALS_INFO_1002
*)buffer
;
2777 return set_USER_MODALS_INFO_1002_buffer(mem_ctx
,
2782 info1003
= (struct USER_MODALS_INFO_1003
*)buffer
;
2783 return set_USER_MODALS_INFO_1003_buffer(mem_ctx
,
2788 info1004
= (struct USER_MODALS_INFO_1004
*)buffer
;
2789 return set_USER_MODALS_INFO_1004_buffer(mem_ctx
,
2794 info1005
= (struct USER_MODALS_INFO_1005
*)buffer
;
2795 return set_USER_MODALS_INFO_1005_buffer(mem_ctx
,
2804 return NT_STATUS_OK
;
2807 /****************************************************************
2808 ****************************************************************/
2810 WERROR
NetUserModalsSet_r(struct libnetapi_ctx
*ctx
,
2811 struct NetUserModalsSet
*r
)
2813 struct rpc_pipe_client
*pipe_cli
= NULL
;
2817 struct policy_handle connect_handle
, domain_handle
;
2818 struct dom_sid2
*domain_sid
= NULL
;
2819 uint32_t access_mask
= SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
;
2821 ZERO_STRUCT(connect_handle
);
2822 ZERO_STRUCT(domain_handle
);
2824 if (!r
->in
.buffer
) {
2825 return WERR_INVALID_PARAM
;
2828 switch (r
->in
.level
) {
2830 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2831 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2832 SAMR_DOMAIN_ACCESS_SET_INFO_1
|
2833 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2840 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
2841 SAMR_DOMAIN_ACCESS_SET_INFO_1
;
2844 access_mask
|= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
2845 SAMR_DOMAIN_ACCESS_SET_INFO_2
;
2851 werr
= WERR_NOT_SUPPORTED
;
2854 werr
= WERR_UNKNOWN_LEVEL
;
2858 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2859 &ndr_table_samr
.syntax_id
,
2861 if (!W_ERROR_IS_OK(werr
)) {
2865 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
2866 SAMR_ACCESS_ENUM_DOMAINS
|
2867 SAMR_ACCESS_LOOKUP_DOMAIN
,
2872 if (!W_ERROR_IS_OK(werr
)) {
2876 status
= set_USER_MODALS_INFO_buffer(ctx
,
2882 if (!NT_STATUS_IS_OK(status
)) {
2883 werr
= ntstatus_to_werror(status
);
2888 if (ctx
->disable_policy_handle_cache
) {
2889 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
2890 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
2896 /****************************************************************
2897 ****************************************************************/
2899 WERROR
NetUserModalsSet_l(struct libnetapi_ctx
*ctx
,
2900 struct NetUserModalsSet
*r
)
2902 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserModalsSet
);
2905 /****************************************************************
2906 ****************************************************************/
2908 NTSTATUS
add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
2910 const char *group_name
,
2911 uint32_t attributes
,
2913 uint32_t *num_entries
)
2915 struct GROUP_USERS_INFO_0 u0
;
2916 struct GROUP_USERS_INFO_1 u1
;
2921 u0
.grui0_name
= talloc_strdup(mem_ctx
, group_name
);
2922 NT_STATUS_HAVE_NO_MEMORY(u0
.grui0_name
);
2924 u0
.grui0_name
= NULL
;
2927 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_0
, u0
,
2928 (struct GROUP_USERS_INFO_0
**)buffer
, num_entries
);
2932 u1
.grui1_name
= talloc_strdup(mem_ctx
, group_name
);
2933 NT_STATUS_HAVE_NO_MEMORY(u1
.grui1_name
);
2935 u1
.grui1_name
= NULL
;
2938 u1
.grui1_attributes
= attributes
;
2940 ADD_TO_ARRAY(mem_ctx
, struct GROUP_USERS_INFO_1
, u1
,
2941 (struct GROUP_USERS_INFO_1
**)buffer
, num_entries
);
2944 return NT_STATUS_INVALID_INFO_CLASS
;
2947 return NT_STATUS_OK
;
2950 /****************************************************************
2951 ****************************************************************/
2953 WERROR
NetUserGetGroups_r(struct libnetapi_ctx
*ctx
,
2954 struct NetUserGetGroups
*r
)
2956 struct rpc_pipe_client
*pipe_cli
= NULL
;
2957 struct policy_handle connect_handle
, domain_handle
, user_handle
;
2958 struct lsa_String lsa_account_name
;
2959 struct dom_sid2
*domain_sid
= NULL
;
2960 struct samr_Ids user_rids
, name_types
;
2961 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
2962 struct lsa_Strings names
;
2963 struct samr_Ids types
;
2964 uint32_t *rids
= NULL
;
2967 uint32_t entries_read
= 0;
2969 NTSTATUS status
= NT_STATUS_OK
;
2970 NTSTATUS result
= NT_STATUS_OK
;
2972 struct dcerpc_binding_handle
*b
= NULL
;
2974 ZERO_STRUCT(connect_handle
);
2975 ZERO_STRUCT(domain_handle
);
2977 if (!r
->out
.buffer
) {
2978 return WERR_INVALID_PARAM
;
2981 *r
->out
.buffer
= NULL
;
2982 *r
->out
.entries_read
= 0;
2983 *r
->out
.total_entries
= 0;
2985 switch (r
->in
.level
) {
2990 return WERR_UNKNOWN_LEVEL
;
2993 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
2994 &ndr_table_samr
.syntax_id
,
2996 if (!W_ERROR_IS_OK(werr
)) {
3000 b
= pipe_cli
->binding_handle
;
3002 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3003 SAMR_ACCESS_ENUM_DOMAINS
|
3004 SAMR_ACCESS_LOOKUP_DOMAIN
,
3005 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3009 if (!W_ERROR_IS_OK(werr
)) {
3013 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3015 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3022 if (!NT_STATUS_IS_OK(status
)) {
3023 werr
= ntstatus_to_werror(status
);
3026 if (!NT_STATUS_IS_OK(result
)) {
3027 werr
= ntstatus_to_werror(result
);
3031 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3033 SAMR_USER_ACCESS_GET_GROUPS
,
3037 if (!NT_STATUS_IS_OK(status
)) {
3038 werr
= ntstatus_to_werror(status
);
3041 if (!NT_STATUS_IS_OK(result
)) {
3042 werr
= ntstatus_to_werror(result
);
3046 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3050 if (!NT_STATUS_IS_OK(status
)) {
3051 werr
= ntstatus_to_werror(status
);
3054 if (!NT_STATUS_IS_OK(result
)) {
3055 werr
= ntstatus_to_werror(result
);
3059 rids
= talloc_array(ctx
, uint32_t, rid_array
->count
);
3065 for (i
=0; i
< rid_array
->count
; i
++) {
3066 rids
[i
] = rid_array
->rids
[i
].rid
;
3069 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3076 if (!NT_STATUS_IS_OK(status
)) {
3077 werr
= ntstatus_to_werror(status
);
3080 if (!NT_STATUS_IS_OK(result
) &&
3081 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
3082 werr
= ntstatus_to_werror(result
);
3086 for (i
=0; i
< names
.count
; i
++) {
3087 status
= add_GROUP_USERS_INFO_X_buffer(ctx
,
3089 names
.names
[i
].string
,
3090 rid_array
->rids
[i
].attributes
,
3093 if (!NT_STATUS_IS_OK(status
)) {
3094 werr
= ntstatus_to_werror(status
);
3099 *r
->out
.entries_read
= entries_read
;
3100 *r
->out
.total_entries
= entries_read
;
3103 if (ctx
->disable_policy_handle_cache
) {
3104 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3105 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3111 /****************************************************************
3112 ****************************************************************/
3114 WERROR
NetUserGetGroups_l(struct libnetapi_ctx
*ctx
,
3115 struct NetUserGetGroups
*r
)
3117 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetGroups
);
3120 /****************************************************************
3121 ****************************************************************/
3123 WERROR
NetUserSetGroups_r(struct libnetapi_ctx
*ctx
,
3124 struct NetUserSetGroups
*r
)
3126 struct rpc_pipe_client
*pipe_cli
= NULL
;
3127 struct policy_handle connect_handle
, domain_handle
, user_handle
, group_handle
;
3128 struct lsa_String lsa_account_name
;
3129 struct dom_sid2
*domain_sid
= NULL
;
3130 struct samr_Ids user_rids
, name_types
;
3131 struct samr_Ids group_rids
;
3132 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3133 struct lsa_String
*lsa_names
= NULL
;
3135 uint32_t *add_rids
= NULL
;
3136 uint32_t *del_rids
= NULL
;
3137 size_t num_add_rids
= 0;
3138 size_t num_del_rids
= 0;
3140 uint32_t *member_rids
= NULL
;
3142 struct GROUP_USERS_INFO_0
*i0
= NULL
;
3143 struct GROUP_USERS_INFO_1
*i1
= NULL
;
3147 NTSTATUS status
= NT_STATUS_OK
;
3148 NTSTATUS result
= NT_STATUS_OK
;
3150 struct dcerpc_binding_handle
*b
= NULL
;
3152 ZERO_STRUCT(connect_handle
);
3153 ZERO_STRUCT(domain_handle
);
3154 ZERO_STRUCT(group_handle
);
3156 if (!r
->in
.buffer
) {
3157 return WERR_INVALID_PARAM
;
3160 switch (r
->in
.level
) {
3165 return WERR_UNKNOWN_LEVEL
;
3168 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3169 &ndr_table_samr
.syntax_id
,
3171 if (!W_ERROR_IS_OK(werr
)) {
3175 b
= pipe_cli
->binding_handle
;
3177 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3178 SAMR_ACCESS_ENUM_DOMAINS
|
3179 SAMR_ACCESS_LOOKUP_DOMAIN
,
3180 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
3184 if (!W_ERROR_IS_OK(werr
)) {
3188 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3190 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3197 if (!NT_STATUS_IS_OK(status
)) {
3198 werr
= ntstatus_to_werror(status
);
3201 if (!NT_STATUS_IS_OK(result
)) {
3202 werr
= ntstatus_to_werror(result
);
3206 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3208 SAMR_USER_ACCESS_GET_GROUPS
,
3212 if (!NT_STATUS_IS_OK(status
)) {
3213 werr
= ntstatus_to_werror(status
);
3216 if (!NT_STATUS_IS_OK(result
)) {
3217 werr
= ntstatus_to_werror(result
);
3221 switch (r
->in
.level
) {
3223 i0
= (struct GROUP_USERS_INFO_0
*)r
->in
.buffer
;
3226 i1
= (struct GROUP_USERS_INFO_1
*)r
->in
.buffer
;
3230 lsa_names
= talloc_array(ctx
, struct lsa_String
, r
->in
.num_entries
);
3236 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3238 switch (r
->in
.level
) {
3240 init_lsa_String(&lsa_names
[i
], i0
->grui0_name
);
3244 init_lsa_String(&lsa_names
[i
], i1
->grui1_name
);
3250 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3257 if (!NT_STATUS_IS_OK(status
)) {
3258 werr
= ntstatus_to_werror(status
);
3261 if (!NT_STATUS_IS_OK(result
)) {
3262 werr
= ntstatus_to_werror(result
);
3266 member_rids
= group_rids
.ids
;
3268 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3272 if (!NT_STATUS_IS_OK(status
)) {
3273 werr
= ntstatus_to_werror(status
);
3276 if (!NT_STATUS_IS_OK(result
)) {
3277 werr
= ntstatus_to_werror(result
);
3283 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3284 bool already_member
= false;
3285 for (k
=0; k
< rid_array
->count
; k
++) {
3286 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3287 already_member
= true;
3291 if (!already_member
) {
3292 if (!add_rid_to_array_unique(ctx
,
3294 &add_rids
, &num_add_rids
)) {
3295 werr
= WERR_GENERAL_FAILURE
;
3303 for (k
=0; k
< rid_array
->count
; k
++) {
3304 bool keep_member
= false;
3305 for (i
=0; i
< r
->in
.num_entries
; i
++) {
3306 if (member_rids
[i
] == rid_array
->rids
[k
].rid
) {
3312 if (!add_rid_to_array_unique(ctx
,
3313 rid_array
->rids
[k
].rid
,
3314 &del_rids
, &num_del_rids
)) {
3315 werr
= WERR_GENERAL_FAILURE
;
3323 for (i
=0; i
< num_add_rids
; i
++) {
3324 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3326 SAMR_GROUP_ACCESS_ADD_MEMBER
,
3330 if (!NT_STATUS_IS_OK(status
)) {
3331 werr
= ntstatus_to_werror(status
);
3334 if (!NT_STATUS_IS_OK(result
)) {
3335 werr
= ntstatus_to_werror(result
);
3339 status
= dcerpc_samr_AddGroupMember(b
, talloc_tos(),
3344 if (!NT_STATUS_IS_OK(status
)) {
3345 werr
= ntstatus_to_werror(status
);
3348 if (!NT_STATUS_IS_OK(result
)) {
3349 werr
= ntstatus_to_werror(result
);
3353 if (is_valid_policy_hnd(&group_handle
)) {
3354 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3360 for (i
=0; i
< num_del_rids
; i
++) {
3361 status
= dcerpc_samr_OpenGroup(b
, talloc_tos(),
3363 SAMR_GROUP_ACCESS_REMOVE_MEMBER
,
3367 if (!NT_STATUS_IS_OK(status
)) {
3368 werr
= ntstatus_to_werror(status
);
3371 if (!NT_STATUS_IS_OK(result
)) {
3372 werr
= ntstatus_to_werror(result
);
3376 status
= dcerpc_samr_DeleteGroupMember(b
, talloc_tos(),
3380 if (!NT_STATUS_IS_OK(status
)) {
3381 werr
= ntstatus_to_werror(status
);
3384 if (!NT_STATUS_IS_OK(result
)) {
3385 werr
= ntstatus_to_werror(result
);
3389 if (is_valid_policy_hnd(&group_handle
)) {
3390 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3397 if (is_valid_policy_hnd(&group_handle
)) {
3398 dcerpc_samr_Close(b
, talloc_tos(), &group_handle
, &result
);
3401 if (ctx
->disable_policy_handle_cache
) {
3402 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3403 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3409 /****************************************************************
3410 ****************************************************************/
3412 WERROR
NetUserSetGroups_l(struct libnetapi_ctx
*ctx
,
3413 struct NetUserSetGroups
*r
)
3415 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserSetGroups
);
3418 /****************************************************************
3419 ****************************************************************/
3421 static NTSTATUS
add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX
*mem_ctx
,
3423 const char *group_name
,
3425 uint32_t *num_entries
)
3427 struct LOCALGROUP_USERS_INFO_0 u0
;
3431 u0
.lgrui0_name
= talloc_strdup(mem_ctx
, group_name
);
3432 NT_STATUS_HAVE_NO_MEMORY(u0
.lgrui0_name
);
3434 ADD_TO_ARRAY(mem_ctx
, struct LOCALGROUP_USERS_INFO_0
, u0
,
3435 (struct LOCALGROUP_USERS_INFO_0
**)buffer
, num_entries
);
3438 return NT_STATUS_INVALID_INFO_CLASS
;
3441 return NT_STATUS_OK
;
3444 /****************************************************************
3445 ****************************************************************/
3447 WERROR
NetUserGetLocalGroups_r(struct libnetapi_ctx
*ctx
,
3448 struct NetUserGetLocalGroups
*r
)
3450 struct rpc_pipe_client
*pipe_cli
= NULL
;
3451 struct policy_handle connect_handle
, domain_handle
, user_handle
,
3453 struct lsa_String lsa_account_name
;
3454 struct dom_sid2
*domain_sid
= NULL
;
3455 struct samr_Ids user_rids
, name_types
;
3456 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
3457 struct lsa_Strings names
;
3458 struct samr_Ids types
;
3459 uint32_t *rids
= NULL
;
3460 size_t num_rids
= 0;
3461 struct dom_sid user_sid
;
3462 struct lsa_SidArray sid_array
;
3463 struct samr_Ids domain_rids
;
3464 struct samr_Ids builtin_rids
;
3467 uint32_t entries_read
= 0;
3469 NTSTATUS status
= NT_STATUS_OK
;
3470 NTSTATUS result
= NT_STATUS_OK
;
3472 struct dcerpc_binding_handle
*b
= NULL
;
3474 ZERO_STRUCT(connect_handle
);
3475 ZERO_STRUCT(domain_handle
);
3477 if (!r
->out
.buffer
) {
3478 return WERR_INVALID_PARAM
;
3481 *r
->out
.buffer
= NULL
;
3482 *r
->out
.entries_read
= 0;
3483 *r
->out
.total_entries
= 0;
3485 switch (r
->in
.level
) {
3490 return WERR_UNKNOWN_LEVEL
;
3493 werr
= libnetapi_open_pipe(ctx
, r
->in
.server_name
,
3494 &ndr_table_samr
.syntax_id
,
3496 if (!W_ERROR_IS_OK(werr
)) {
3500 b
= pipe_cli
->binding_handle
;
3502 werr
= libnetapi_samr_open_domain(ctx
, pipe_cli
,
3503 SAMR_ACCESS_ENUM_DOMAINS
|
3504 SAMR_ACCESS_LOOKUP_DOMAIN
,
3505 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3506 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3510 if (!W_ERROR_IS_OK(werr
)) {
3514 werr
= libnetapi_samr_open_builtin_domain(ctx
, pipe_cli
,
3515 SAMR_ACCESS_ENUM_DOMAINS
|
3516 SAMR_ACCESS_LOOKUP_DOMAIN
,
3517 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
|
3518 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
,
3521 if (!W_ERROR_IS_OK(werr
)) {
3525 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
3527 status
= dcerpc_samr_LookupNames(b
, talloc_tos(),
3534 if (!NT_STATUS_IS_OK(status
)) {
3535 werr
= ntstatus_to_werror(status
);
3538 if (!NT_STATUS_IS_OK(result
)) {
3539 werr
= ntstatus_to_werror(result
);
3543 status
= dcerpc_samr_OpenUser(b
, talloc_tos(),
3545 SAMR_USER_ACCESS_GET_GROUPS
,
3549 if (!NT_STATUS_IS_OK(status
)) {
3550 werr
= ntstatus_to_werror(status
);
3553 if (!NT_STATUS_IS_OK(result
)) {
3554 werr
= ntstatus_to_werror(result
);
3558 status
= dcerpc_samr_GetGroupsForUser(b
, talloc_tos(),
3562 if (!NT_STATUS_IS_OK(status
)) {
3563 werr
= ntstatus_to_werror(status
);
3566 if (!NT_STATUS_IS_OK(result
)) {
3567 werr
= ntstatus_to_werror(result
);
3571 if (!sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0])) {
3576 sid_array
.num_sids
= rid_array
->count
+ 1;
3577 sid_array
.sids
= talloc_array(ctx
, struct lsa_SidPtr
, sid_array
.num_sids
);
3578 if (!sid_array
.sids
) {
3583 sid_array
.sids
[0].sid
= dom_sid_dup(ctx
, &user_sid
);
3584 if (!sid_array
.sids
[0].sid
) {
3589 for (i
=0; i
< rid_array
->count
; i
++) {
3592 if (!sid_compose(&sid
, domain_sid
, rid_array
->rids
[i
].rid
)) {
3597 sid_array
.sids
[i
+1].sid
= dom_sid_dup(ctx
, &sid
);
3598 if (!sid_array
.sids
[i
+1].sid
) {
3604 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3609 if (!NT_STATUS_IS_OK(status
)) {
3610 werr
= ntstatus_to_werror(status
);
3613 if (!NT_STATUS_IS_OK(result
)) {
3614 werr
= ntstatus_to_werror(result
);
3618 for (i
=0; i
< domain_rids
.count
; i
++) {
3619 if (!add_rid_to_array_unique(ctx
, domain_rids
.ids
[i
],
3620 &rids
, &num_rids
)) {
3626 status
= dcerpc_samr_GetAliasMembership(b
, talloc_tos(),
3631 if (!NT_STATUS_IS_OK(status
)) {
3632 werr
= ntstatus_to_werror(status
);
3635 if (!NT_STATUS_IS_OK(result
)) {
3636 werr
= ntstatus_to_werror(result
);
3640 for (i
=0; i
< builtin_rids
.count
; i
++) {
3641 if (!add_rid_to_array_unique(ctx
, builtin_rids
.ids
[i
],
3642 &rids
, &num_rids
)) {
3648 status
= dcerpc_samr_LookupRids(b
, talloc_tos(),
3655 if (!NT_STATUS_IS_OK(status
)) {
3656 werr
= ntstatus_to_werror(status
);
3659 if (!NT_STATUS_IS_OK(result
)) {
3660 werr
= ntstatus_to_werror(result
);
3664 for (i
=0; i
< names
.count
; i
++) {
3665 status
= add_LOCALGROUP_USERS_INFO_X_buffer(ctx
,
3667 names
.names
[i
].string
,
3670 if (!NT_STATUS_IS_OK(status
)) {
3671 werr
= ntstatus_to_werror(status
);
3676 *r
->out
.entries_read
= entries_read
;
3677 *r
->out
.total_entries
= entries_read
;
3680 if (ctx
->disable_policy_handle_cache
) {
3681 libnetapi_samr_close_domain_handle(ctx
, &domain_handle
);
3682 libnetapi_samr_close_connect_handle(ctx
, &connect_handle
);
3688 /****************************************************************
3689 ****************************************************************/
3691 WERROR
NetUserGetLocalGroups_l(struct libnetapi_ctx
*ctx
,
3692 struct NetUserGetLocalGroups
*r
)
3694 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx
, r
, NetUserGetLocalGroups
);