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"
27 /****************************************************************
28 ****************************************************************/
30 static void convert_USER_INFO_1_to_samr_user_info25(struct USER_INFO_1
*info1
,
31 DATA_BLOB
*user_session_key
,
32 struct samr_UserInfo25
*info25
)
34 uint32_t fields_present
= SAMR_FIELD_ACCT_FLAGS
;
35 struct samr_LogonHours zero_logon_hours
;
36 struct lsa_BinaryString zero_parameters
;
37 uint32_t acct_flags
= 0;
41 ZERO_STRUCT(zero_logon_hours
);
42 ZERO_STRUCT(zero_parameters
);
44 if (info1
->usri1_name
) {
45 fields_present
|= SAMR_FIELD_FULL_NAME
;
47 if (info1
->usri1_password
) {
48 fields_present
|= SAMR_FIELD_PASSWORD
;
50 if (info1
->usri1_flags
) {
51 fields_present
|= SAMR_FIELD_ACCT_FLAGS
;
53 if (info1
->usri1_name
) {
54 fields_present
|= SAMR_FIELD_FULL_NAME
;
56 if (info1
->usri1_home_dir
) {
57 fields_present
|= SAMR_FIELD_HOME_DIRECTORY
;
59 if (info1
->usri1_script_path
) {
60 fields_present
|= SAMR_FIELD_LOGON_SCRIPT
;
62 if (info1
->usri1_comment
) {
63 fields_present
|= SAMR_FIELD_DESCRIPTION
;
65 if (info1
->usri1_password_age
) {
66 fields_present
|= SAMR_FIELD_FORCE_PWD_CHANGE
;
69 acct_flags
|= info1
->usri1_flags
| ACB_NORMAL
;
71 unix_to_nt_time_abs(&password_age
, info1
->usri1_password_age
);
73 /* TODO: info1->usri1_priv */
74 init_samr_user_info21(&info25
->info
,
83 info1
->usri1_home_dir
,
85 info1
->usri1_script_path
,
104 if (info1
->usri1_password
) {
106 struct MD5Context ctx
;
107 uint8_t confounder
[16];
108 DATA_BLOB confounded_session_key
= data_blob(NULL
, 16);
110 encode_pw_buffer(pwbuf
, info1
->usri1_password
, STR_UNICODE
);
112 generate_random_buffer((uint8_t *)confounder
, 16);
115 MD5Update(&ctx
, confounder
, 16);
116 MD5Update(&ctx
, user_session_key
->data
,
117 user_session_key
->length
);
118 MD5Final(confounded_session_key
.data
, &ctx
);
120 SamOEMhashBlob(pwbuf
, 516, &confounded_session_key
);
121 memcpy(&pwbuf
[516], confounder
, 16);
123 memcpy(info25
->password
.data
, pwbuf
, sizeof(pwbuf
));
124 data_blob_free(&confounded_session_key
);
128 /****************************************************************
129 ****************************************************************/
131 WERROR
NetUserAdd_r(struct libnetapi_ctx
*ctx
,
132 struct NetUserAdd
*r
)
134 struct cli_state
*cli
= NULL
;
135 struct rpc_pipe_client
*pipe_cli
= NULL
;
138 uint32_t resume_handle
= 0;
139 uint32_t num_entries
= 0;
140 POLICY_HND connect_handle
, domain_handle
, user_handle
;
141 struct samr_SamArray
*sam
= NULL
;
142 const char *domain_name
= NULL
;
143 struct lsa_String lsa_domain_name
, lsa_account_name
;
144 struct dom_sid2
*domain_sid
= NULL
;
145 struct samr_UserInfo25 info25
;
146 union samr_UserInfo
*user_info
= NULL
;
147 struct samr_PwInfo pw_info
;
148 uint32_t access_granted
= 0;
150 bool domain_found
= true;
152 struct USER_INFO_1
*info1
;
154 ZERO_STRUCT(connect_handle
);
155 ZERO_STRUCT(domain_handle
);
156 ZERO_STRUCT(user_handle
);
159 return WERR_INVALID_PARAM
;
162 switch (r
->in
.level
) {
164 info1
= (struct USER_INFO_1
*)r
->in
.buffer
;
170 werr
= WERR_NOT_SUPPORTED
;
174 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
175 if (!W_ERROR_IS_OK(werr
)) {
179 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
180 if (!W_ERROR_IS_OK(werr
)) {
184 status
= rpccli_try_samr_connects(pipe_cli
, ctx
,
185 SAMR_ACCESS_ENUM_DOMAINS
|
186 SAMR_ACCESS_OPEN_DOMAIN
,
188 if (!NT_STATUS_IS_OK(status
)) {
189 werr
= ntstatus_to_werror(status
);
193 status
= rpccli_samr_EnumDomains(pipe_cli
, ctx
,
199 if (!NT_STATUS_IS_OK(status
)) {
200 werr
= ntstatus_to_werror(status
);
204 for (i
=0; i
<num_entries
; i
++) {
206 domain_name
= sam
->entries
[i
].name
.string
;
208 if (strequal(domain_name
, builtin_domain_name())) {
217 werr
= WERR_NO_SUCH_DOMAIN
;
221 init_lsa_String(&lsa_domain_name
, domain_name
);
223 status
= rpccli_samr_LookupDomain(pipe_cli
, ctx
,
227 if (!NT_STATUS_IS_OK(status
)) {
228 werr
= ntstatus_to_werror(status
);
232 status
= rpccli_samr_OpenDomain(pipe_cli
, ctx
,
234 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
|
235 SAMR_DOMAIN_ACCESS_CREATE_USER
|
236 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
239 if (!NT_STATUS_IS_OK(status
)) {
240 werr
= ntstatus_to_werror(status
);
244 init_lsa_String(&lsa_account_name
, info1
->usri1_name
);
246 status
= rpccli_samr_CreateUser2(pipe_cli
, ctx
,
252 SAMR_USER_ACCESS_SET_PASSWORD
|
253 SAMR_USER_ACCESS_SET_ATTRIBUTES
|
254 SAMR_USER_ACCESS_GET_ATTRIBUTES
,
258 if (!NT_STATUS_IS_OK(status
)) {
259 werr
= ntstatus_to_werror(status
);
263 status
= rpccli_samr_QueryUserInfo(pipe_cli
, ctx
,
267 if (!NT_STATUS_IS_OK(status
)) {
268 werr
= ntstatus_to_werror(status
);
272 if (!(user_info
->info16
.acct_flags
& ACB_NORMAL
)) {
273 werr
= WERR_INVALID_PARAM
;
277 status
= rpccli_samr_GetUserPwInfo(pipe_cli
, ctx
,
280 if (!NT_STATUS_IS_OK(status
)) {
281 werr
= ntstatus_to_werror(status
);
285 ZERO_STRUCTP(user_info
);
287 convert_USER_INFO_1_to_samr_user_info25(info1
,
288 &cli
->user_session_key
,
291 if (info1
->usri1_password
) {
292 user_info
->info25
= info25
;
293 status
= rpccli_samr_SetUserInfo2(pipe_cli
, ctx
,
298 user_info
->info21
= info25
.info
;
299 status
= rpccli_samr_SetUserInfo(pipe_cli
, ctx
,
305 if (!NT_STATUS_IS_OK(status
)) {
306 werr
= ntstatus_to_werror(status
);
314 rpccli_samr_DeleteUser(pipe_cli
, ctx
,
322 if (is_valid_policy_hnd(&user_handle
)) {
323 rpccli_samr_Close(pipe_cli
, ctx
, &user_handle
);
325 if (is_valid_policy_hnd(&domain_handle
)) {
326 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
328 if (is_valid_policy_hnd(&connect_handle
)) {
329 rpccli_samr_Close(pipe_cli
, ctx
, &connect_handle
);
335 /****************************************************************
336 ****************************************************************/
338 WERROR
NetUserAdd_l(struct libnetapi_ctx
*ctx
,
339 struct NetUserAdd
*r
)
341 /* for now just talk to local RPC server */
342 if (!r
->in
.server_name
) {
343 r
->in
.server_name
= "localhost";
346 return NetUserAdd_r(ctx
, r
);
349 /****************************************************************
350 ****************************************************************/
352 WERROR
NetUserDel_r(struct libnetapi_ctx
*ctx
,
353 struct NetUserDel
*r
)
355 struct cli_state
*cli
= NULL
;
356 struct rpc_pipe_client
*pipe_cli
= NULL
;
359 uint32_t resume_handle
= 0;
360 uint32_t num_entries
= 0;
361 POLICY_HND connect_handle
, builtin_handle
, domain_handle
, user_handle
;
362 struct samr_SamArray
*sam
= NULL
;
363 const char *domain_name
= NULL
;
364 struct lsa_String lsa_domain_name
, lsa_account_name
;
365 struct samr_Ids user_rids
, name_types
;
366 struct dom_sid2
*domain_sid
= NULL
;
367 struct dom_sid2 user_sid
;
368 bool domain_found
= true;
371 ZERO_STRUCT(connect_handle
);
372 ZERO_STRUCT(builtin_handle
);
373 ZERO_STRUCT(domain_handle
);
374 ZERO_STRUCT(user_handle
);
376 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
377 if (!W_ERROR_IS_OK(werr
)) {
381 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
382 if (!W_ERROR_IS_OK(werr
)) {
386 status
= rpccli_try_samr_connects(pipe_cli
, ctx
,
387 SAMR_ACCESS_ENUM_DOMAINS
|
388 SAMR_ACCESS_OPEN_DOMAIN
,
390 if (!NT_STATUS_IS_OK(status
)) {
391 werr
= ntstatus_to_werror(status
);
395 status
= rpccli_samr_EnumDomains(pipe_cli
, ctx
,
401 if (!NT_STATUS_IS_OK(status
)) {
402 werr
= ntstatus_to_werror(status
);
406 for (i
=0; i
<num_entries
; i
++) {
408 domain_name
= sam
->entries
[i
].name
.string
;
410 if (strequal(domain_name
, builtin_domain_name())) {
419 werr
= WERR_NO_SUCH_DOMAIN
;
423 init_lsa_String(&lsa_domain_name
, domain_name
);
425 status
= rpccli_samr_LookupDomain(pipe_cli
, ctx
,
429 if (!NT_STATUS_IS_OK(status
)) {
430 werr
= ntstatus_to_werror(status
);
434 status
= rpccli_samr_OpenDomain(pipe_cli
, ctx
,
436 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
439 if (!NT_STATUS_IS_OK(status
)) {
440 werr
= ntstatus_to_werror(status
);
444 status
= rpccli_samr_OpenDomain(pipe_cli
, ctx
,
446 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
447 CONST_DISCARD(DOM_SID
*, &global_sid_Builtin
),
449 if (!NT_STATUS_IS_OK(status
)) {
450 werr
= ntstatus_to_werror(status
);
454 init_lsa_String(&lsa_account_name
, r
->in
.user_name
);
456 status
= rpccli_samr_LookupNames(pipe_cli
, ctx
,
462 if (!NT_STATUS_IS_OK(status
)) {
463 werr
= ntstatus_to_werror(status
);
467 status
= rpccli_samr_OpenUser(pipe_cli
, ctx
,
469 STD_RIGHT_DELETE_ACCESS
,
472 if (!NT_STATUS_IS_OK(status
)) {
473 werr
= ntstatus_to_werror(status
);
477 sid_compose(&user_sid
, domain_sid
, user_rids
.ids
[0]);
479 status
= rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli
, ctx
,
482 if (!NT_STATUS_IS_OK(status
)) {
483 werr
= ntstatus_to_werror(status
);
487 status
= rpccli_samr_DeleteUser(pipe_cli
, ctx
,
489 if (!NT_STATUS_IS_OK(status
)) {
490 werr
= ntstatus_to_werror(status
);
501 if (is_valid_policy_hnd(&user_handle
)) {
502 rpccli_samr_Close(pipe_cli
, ctx
, &user_handle
);
504 if (is_valid_policy_hnd(&builtin_handle
)) {
505 rpccli_samr_Close(pipe_cli
, ctx
, &builtin_handle
);
507 if (is_valid_policy_hnd(&domain_handle
)) {
508 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
510 if (is_valid_policy_hnd(&connect_handle
)) {
511 rpccli_samr_Close(pipe_cli
, ctx
, &connect_handle
);
517 /****************************************************************
518 ****************************************************************/
520 WERROR
NetUserDel_l(struct libnetapi_ctx
*ctx
,
521 struct NetUserDel
*r
)
523 /* for now just talk to local RPC server */
524 if (!r
->in
.server_name
) {
525 r
->in
.server_name
= "localhost";
528 return NetUserDel_r(ctx
, r
);
531 /****************************************************************
532 ****************************************************************/
534 static WERROR
convert_samr_samarray_to_USER_INFO_buffer(TALLOC_CTX
*mem_ctx
,
535 struct samr_SamArray
*sam_array
,
539 struct USER_INFO_0
*info0
= NULL
;
544 info0
= TALLOC_ZERO_ARRAY(mem_ctx
, struct USER_INFO_0
,
546 W_ERROR_HAVE_NO_MEMORY(info0
);
548 for (i
=0; i
<sam_array
->count
; i
++) {
549 info0
[i
].usri0_name
= talloc_strdup(mem_ctx
,
550 sam_array
->entries
[i
].name
.string
);
551 W_ERROR_HAVE_NO_MEMORY(info0
[i
].usri0_name
);
554 *buffer
= (uint8_t *)talloc_memdup(mem_ctx
, info0
,
555 sizeof(struct USER_INFO_0
) * sam_array
->count
);
556 W_ERROR_HAVE_NO_MEMORY(*buffer
);
559 return WERR_NOT_SUPPORTED
;
565 /****************************************************************
566 ****************************************************************/
568 WERROR
NetUserEnum_r(struct libnetapi_ctx
*ctx
,
569 struct NetUserEnum
*r
)
571 struct cli_state
*cli
= NULL
;
572 struct rpc_pipe_client
*pipe_cli
= NULL
;
573 struct policy_handle connect_handle
;
574 struct dom_sid2
*domain_sid
= NULL
;
575 struct policy_handle domain_handle
;
576 struct samr_SamArray
*sam
= NULL
;
577 uint32_t num_entries
= 0;
579 const char *domain_name
= NULL
;
580 bool domain_found
= true;
581 uint32_t dom_resume_handle
= 0;
582 struct lsa_String lsa_domain_name
;
587 ZERO_STRUCT(connect_handle
);
588 ZERO_STRUCT(domain_handle
);
590 switch (r
->in
.level
) {
601 return WERR_NOT_SUPPORTED
;
604 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
605 if (!W_ERROR_IS_OK(werr
)) {
609 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
610 if (!W_ERROR_IS_OK(werr
)) {
614 status
= rpccli_try_samr_connects(pipe_cli
, ctx
,
615 SAMR_ACCESS_OPEN_DOMAIN
|
616 SAMR_ACCESS_ENUM_DOMAINS
,
618 if (!NT_STATUS_IS_OK(status
)) {
619 werr
= ntstatus_to_werror(status
);
623 status
= rpccli_samr_EnumDomains(pipe_cli
, ctx
,
629 if (!NT_STATUS_IS_OK(status
)) {
630 werr
= ntstatus_to_werror(status
);
634 for (i
=0; i
<num_entries
; i
++) {
636 domain_name
= sam
->entries
[i
].name
.string
;
638 if (strequal(domain_name
, builtin_domain_name())) {
647 werr
= WERR_NO_SUCH_DOMAIN
;
651 init_lsa_String(&lsa_domain_name
, domain_name
);
653 status
= rpccli_samr_LookupDomain(pipe_cli
, ctx
,
657 if (!NT_STATUS_IS_OK(status
)) {
658 werr
= ntstatus_to_werror(status
);
662 status
= rpccli_samr_OpenDomain(pipe_cli
,
665 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2
|
666 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
667 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
670 if (!NT_STATUS_IS_OK(status
)) {
671 werr
= ntstatus_to_werror(status
);
675 status
= rpccli_samr_EnumDomainUsers(pipe_cli
,
682 r
->out
.entries_read
);
683 if (!NT_STATUS_IS_OK(status
)) {
684 werr
= ntstatus_to_werror(status
);
688 werr
= convert_samr_samarray_to_USER_INFO_buffer(ctx
, sam
,
697 if (is_valid_policy_hnd(&domain_handle
)) {
698 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
700 if (is_valid_policy_hnd(&connect_handle
)) {
701 rpccli_samr_Close(pipe_cli
, ctx
, &connect_handle
);
707 /****************************************************************
708 ****************************************************************/
710 WERROR
NetUserEnum_l(struct libnetapi_ctx
*ctx
,
711 struct NetUserEnum
*r
)
713 return WERR_NOT_SUPPORTED
;
716 /****************************************************************
717 ****************************************************************/
719 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX
*mem_ctx
,
720 struct samr_DispInfoGeneral
*info
,
721 uint32_t *entries_read
,
724 struct NET_DISPLAY_USER
*user
= NULL
;
727 user
= TALLOC_ZERO_ARRAY(mem_ctx
,
728 struct NET_DISPLAY_USER
,
730 W_ERROR_HAVE_NO_MEMORY(user
);
732 for (i
= 0; i
< info
->count
; i
++) {
733 user
[i
].usri1_name
= talloc_strdup(mem_ctx
,
734 info
->entries
[i
].account_name
.string
);
735 user
[i
].usri1_comment
= talloc_strdup(mem_ctx
,
736 info
->entries
[i
].description
.string
);
737 user
[i
].usri1_flags
=
738 info
->entries
[i
].acct_flags
;
739 user
[i
].usri1_full_name
= talloc_strdup(mem_ctx
,
740 info
->entries
[i
].full_name
.string
);
741 user
[i
].usri1_user_id
=
742 info
->entries
[i
].rid
;
743 user
[i
].usri1_next_index
=
744 info
->entries
[i
].idx
;
746 if (!user
[i
].usri1_name
) {
751 *buffer
= talloc_memdup(mem_ctx
, user
,
752 sizeof(struct NET_DISPLAY_USER
) * info
->count
);
753 W_ERROR_HAVE_NO_MEMORY(*buffer
);
755 *entries_read
= info
->count
;
760 /****************************************************************
761 ****************************************************************/
763 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX
*mem_ctx
,
764 struct samr_DispInfoFull
*info
,
765 uint32_t *entries_read
,
768 struct NET_DISPLAY_MACHINE
*machine
= NULL
;
771 machine
= TALLOC_ZERO_ARRAY(mem_ctx
,
772 struct NET_DISPLAY_MACHINE
,
774 W_ERROR_HAVE_NO_MEMORY(machine
);
776 for (i
= 0; i
< info
->count
; i
++) {
777 machine
[i
].usri2_name
= talloc_strdup(mem_ctx
,
778 info
->entries
[i
].account_name
.string
);
779 machine
[i
].usri2_comment
= talloc_strdup(mem_ctx
,
780 info
->entries
[i
].description
.string
);
781 machine
[i
].usri2_flags
=
782 info
->entries
[i
].acct_flags
;
783 machine
[i
].usri2_user_id
=
784 info
->entries
[i
].rid
;
785 machine
[i
].usri2_next_index
=
786 info
->entries
[i
].idx
;
788 if (!machine
[i
].usri2_name
) {
793 *buffer
= talloc_memdup(mem_ctx
, machine
,
794 sizeof(struct NET_DISPLAY_MACHINE
) * info
->count
);
795 W_ERROR_HAVE_NO_MEMORY(*buffer
);
797 *entries_read
= info
->count
;
802 /****************************************************************
803 ****************************************************************/
805 static WERROR
convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX
*mem_ctx
,
806 struct samr_DispInfoFullGroups
*info
,
807 uint32_t *entries_read
,
810 struct NET_DISPLAY_GROUP
*group
= NULL
;
813 group
= TALLOC_ZERO_ARRAY(mem_ctx
,
814 struct NET_DISPLAY_GROUP
,
816 W_ERROR_HAVE_NO_MEMORY(group
);
818 for (i
= 0; i
< info
->count
; i
++) {
819 group
[i
].grpi3_name
= talloc_strdup(mem_ctx
,
820 info
->entries
[i
].account_name
.string
);
821 group
[i
].grpi3_comment
= talloc_strdup(mem_ctx
,
822 info
->entries
[i
].description
.string
);
823 group
[i
].grpi3_group_id
=
824 info
->entries
[i
].rid
;
825 group
[i
].grpi3_attributes
=
826 info
->entries
[i
].acct_flags
;
827 group
[i
].grpi3_next_index
=
828 info
->entries
[i
].idx
;
830 if (!group
[i
].grpi3_name
) {
835 *buffer
= talloc_memdup(mem_ctx
, group
,
836 sizeof(struct NET_DISPLAY_GROUP
) * info
->count
);
837 W_ERROR_HAVE_NO_MEMORY(*buffer
);
839 *entries_read
= info
->count
;
845 /****************************************************************
846 ****************************************************************/
848 WERROR
convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX
*mem_ctx
,
849 union samr_DispInfo
*info
,
851 uint32_t *entries_read
,
856 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx
,
861 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx
,
866 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx
,
871 return WERR_UNKNOWN_LEVEL
;
877 /****************************************************************
878 ****************************************************************/
880 WERROR
NetQueryDisplayInformation_r(struct libnetapi_ctx
*ctx
,
881 struct NetQueryDisplayInformation
*r
)
883 struct cli_state
*cli
= NULL
;
884 struct rpc_pipe_client
*pipe_cli
= NULL
;
885 struct policy_handle connect_handle
;
886 struct dom_sid2
*domain_sid
= NULL
;
887 struct policy_handle domain_handle
;
888 union samr_DispInfo info
;
889 struct samr_SamArray
*sam
= NULL
;
890 uint32_t num_entries
= 0;
892 const char *domain_name
= NULL
;
893 bool domain_found
= true;
894 uint32_t dom_resume_handle
= 0;
895 struct lsa_String lsa_domain_name
;
897 uint32_t total_size
= 0;
898 uint32_t returned_size
= 0;
904 *r
->out
.entries_read
= 0;
906 ZERO_STRUCT(connect_handle
);
907 ZERO_STRUCT(domain_handle
);
909 switch (r
->in
.level
) {
915 return WERR_UNKNOWN_LEVEL
;
918 werr
= libnetapi_open_ipc_connection(ctx
, r
->in
.server_name
, &cli
);
919 if (!W_ERROR_IS_OK(werr
)) {
923 werr
= libnetapi_open_pipe(ctx
, cli
, PI_SAMR
, &pipe_cli
);
924 if (!W_ERROR_IS_OK(werr
)) {
928 status
= rpccli_try_samr_connects(pipe_cli
, ctx
,
929 SAMR_ACCESS_OPEN_DOMAIN
|
930 SAMR_ACCESS_ENUM_DOMAINS
,
932 if (!NT_STATUS_IS_OK(status
)) {
933 werr
= ntstatus_to_werror(status
);
937 status
= rpccli_samr_EnumDomains(pipe_cli
, ctx
,
943 if (!NT_STATUS_IS_OK(status
)) {
944 werr
= ntstatus_to_werror(status
);
948 for (i
=0; i
<num_entries
; i
++) {
950 domain_name
= sam
->entries
[i
].name
.string
;
952 if (strequal(domain_name
, builtin_domain_name())) {
961 werr
= WERR_NO_SUCH_DOMAIN
;
965 init_lsa_String(&lsa_domain_name
, domain_name
);
967 status
= rpccli_samr_LookupDomain(pipe_cli
, ctx
,
971 if (!NT_STATUS_IS_OK(status
)) {
972 werr
= ntstatus_to_werror(status
);
976 status
= rpccli_samr_OpenDomain(pipe_cli
,
979 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS
|
980 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT
,
983 if (!NT_STATUS_IS_OK(status
)) {
984 werr
= ntstatus_to_werror(status
);
988 status
= rpccli_samr_QueryDisplayInfo2(pipe_cli
,
993 r
->in
.entries_requested
,
998 werr
= ntstatus_to_werror(status
);
999 if (NT_STATUS_IS_ERR(status
)) {
1003 werr_tmp
= convert_samr_dispinfo_to_NET_DISPLAY(ctx
, &info
,
1005 r
->out
.entries_read
,
1007 if (!W_ERROR_IS_OK(werr_tmp
)) {
1015 if (is_valid_policy_hnd(&domain_handle
)) {
1016 rpccli_samr_Close(pipe_cli
, ctx
, &domain_handle
);
1018 if (is_valid_policy_hnd(&connect_handle
)) {
1019 rpccli_samr_Close(pipe_cli
, ctx
, &connect_handle
);
1026 /****************************************************************
1027 ****************************************************************/
1030 WERROR
NetQueryDisplayInformation_l(struct libnetapi_ctx
*ctx
,
1031 struct NetQueryDisplayInformation
*r
)
1033 return WERR_NOT_SUPPORTED
;