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_X_to_samr_user_info21(struct USER_INFO_X *infoX,
31 struct samr_UserInfo21 *info21)
33 uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS;
34 struct samr_LogonHours zero_logon_hours;
35 struct lsa_BinaryString zero_parameters;
36 uint32_t acct_flags = 0;
40 ZERO_STRUCT(zero_logon_hours);
41 ZERO_STRUCT(zero_parameters);
43 if (infoX->usriX_name) {
44 fields_present |= SAMR_FIELD_FULL_NAME;
46 if (infoX->usriX_password) {
47 fields_present |= SAMR_FIELD_PASSWORD;
49 if (infoX->usriX_flags) {
50 fields_present |= SAMR_FIELD_ACCT_FLAGS;
52 if (infoX->usriX_name) {
53 fields_present |= SAMR_FIELD_FULL_NAME;
55 if (infoX->usriX_home_dir) {
56 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
58 if (infoX->usriX_script_path) {
59 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
61 if (infoX->usriX_comment) {
62 fields_present |= SAMR_FIELD_DESCRIPTION;
64 if (infoX->usriX_password_age) {
65 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
68 acct_flags |= infoX->usriX_flags | ACB_NORMAL;
70 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
72 /* TODO: infoX->usriX_priv */
73 init_samr_user_info21(info21,
82 infoX->usriX_home_dir,
84 infoX->usriX_script_path,
104 /****************************************************************
105 ****************************************************************/
107 static NTSTATUS construct_USER_INFO_X(uint32_t level,
109 struct USER_INFO_X *uX)
111 struct USER_INFO_0 *u0 = NULL;
112 struct USER_INFO_1 *u1 = NULL;
113 struct USER_INFO_2 *u2 = NULL;
114 struct USER_INFO_1007 *u1007 = NULL;
116 if (!buffer || !uX) {
117 return NT_STATUS_INVALID_PARAMETER;
124 u0 = (struct USER_INFO_0 *)buffer;
125 uX->usriX_name = u0->usri0_name;
128 u1 = (struct USER_INFO_1 *)buffer;
129 uX->usriX_name = u1->usri1_name;
130 uX->usriX_password = u1->usri1_password;
131 uX->usriX_password_age = u1->usri1_password_age;
132 uX->usriX_priv = u1->usri1_priv;
133 uX->usriX_home_dir = u1->usri1_home_dir;
134 uX->usriX_comment = u1->usri1_comment;
135 uX->usriX_flags = u1->usri1_flags;
136 uX->usriX_script_path = u1->usri1_script_path;
139 u2 = (struct USER_INFO_2 *)buffer;
140 uX->usriX_name = u2->usri2_name;
141 uX->usriX_password = u2->usri2_password;
142 uX->usriX_password_age = u2->usri2_password_age;
143 uX->usriX_priv = u2->usri2_priv;
144 uX->usriX_home_dir = u2->usri2_home_dir;
145 uX->usriX_comment = u2->usri2_comment;
146 uX->usriX_flags = u2->usri2_flags;
147 uX->usriX_script_path = u2->usri2_script_path;
148 uX->usriX_auth_flags = u2->usri2_auth_flags;
149 uX->usriX_full_name = u2->usri2_full_name;
150 uX->usriX_usr_comment = u2->usri2_usr_comment;
151 uX->usriX_parms = u2->usri2_parms;
152 uX->usriX_workstations = u2->usri2_workstations;
153 uX->usriX_last_logon = u2->usri2_last_logon;
154 uX->usriX_last_logoff = u2->usri2_last_logoff;
155 uX->usriX_acct_expires = u2->usri2_acct_expires;
156 uX->usriX_max_storage = u2->usri2_max_storage;
157 uX->usriX_units_per_week= u2->usri2_units_per_week;
158 uX->usriX_logon_hours = u2->usri2_logon_hours;
159 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
160 uX->usriX_num_logons = u2->usri2_num_logons;
161 uX->usriX_logon_server = u2->usri2_logon_server;
162 uX->usriX_country_code = u2->usri2_country_code;
163 uX->usriX_code_page = u2->usri2_code_page;
166 u1007 = (struct USER_INFO_1007 *)buffer;
167 uX->usriX_comment = u1007->usri1007_comment;
172 return NT_STATUS_INVALID_INFO_CLASS;
178 /****************************************************************
179 ****************************************************************/
181 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
182 struct NetUserAdd *r)
184 struct cli_state *cli = NULL;
185 struct rpc_pipe_client *pipe_cli = NULL;
188 POLICY_HND connect_handle, domain_handle, user_handle;
189 struct lsa_String lsa_account_name;
190 struct dom_sid2 *domain_sid = NULL;
191 struct samr_UserInfo21 info21;
192 union samr_UserInfo *user_info = NULL;
193 struct samr_PwInfo pw_info;
194 uint32_t access_granted = 0;
196 struct USER_INFO_X uX;
198 ZERO_STRUCT(connect_handle);
199 ZERO_STRUCT(domain_handle);
200 ZERO_STRUCT(user_handle);
203 return WERR_INVALID_PARAM;
206 switch (r->in.level) {
213 werr = WERR_NOT_SUPPORTED;
217 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
218 if (!W_ERROR_IS_OK(werr)) {
222 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
224 if (!W_ERROR_IS_OK(werr)) {
228 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
229 if (!NT_STATUS_IS_OK(status)) {
230 werr = ntstatus_to_werror(status);
234 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
235 SAMR_ACCESS_ENUM_DOMAINS |
236 SAMR_ACCESS_OPEN_DOMAIN,
237 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
238 SAMR_DOMAIN_ACCESS_CREATE_USER |
239 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
243 if (!W_ERROR_IS_OK(werr)) {
247 init_lsa_String(&lsa_account_name, uX.usriX_name);
249 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
255 SAMR_USER_ACCESS_SET_PASSWORD |
256 SAMR_USER_ACCESS_SET_ATTRIBUTES |
257 SAMR_USER_ACCESS_GET_ATTRIBUTES,
261 if (!NT_STATUS_IS_OK(status)) {
262 werr = ntstatus_to_werror(status);
266 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
270 if (!NT_STATUS_IS_OK(status)) {
271 werr = ntstatus_to_werror(status);
275 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
276 werr = WERR_INVALID_PARAM;
280 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
283 if (!NT_STATUS_IS_OK(status)) {
284 werr = ntstatus_to_werror(status);
288 convert_USER_INFO_X_to_samr_user_info21(&uX,
291 ZERO_STRUCTP(user_info);
293 if (uX.usriX_password) {
295 user_info->info25.info = info21;
297 init_samr_CryptPasswordEx(uX.usriX_password,
298 &cli->user_session_key,
299 &user_info->info25.password);
301 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
306 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
308 user_info->info23.info = info21;
310 init_samr_CryptPassword(uX.usriX_password,
311 &cli->user_session_key,
312 &user_info->info23.password);
314 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
321 user_info->info21 = info21;
323 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
329 if (!NT_STATUS_IS_OK(status)) {
330 werr = ntstatus_to_werror(status);
338 rpccli_samr_DeleteUser(pipe_cli, ctx,
346 if (is_valid_policy_hnd(&user_handle)) {
347 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
350 if (ctx->disable_policy_handle_cache) {
351 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
352 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
358 /****************************************************************
359 ****************************************************************/
361 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
362 struct NetUserAdd *r)
364 /* for now just talk to local RPC server */
365 if (!r->in.server_name) {
366 r->in.server_name = "localhost";
369 return NetUserAdd_r(ctx, r);
372 /****************************************************************
373 ****************************************************************/
375 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
376 struct NetUserDel *r)
378 struct cli_state *cli = NULL;
379 struct rpc_pipe_client *pipe_cli = NULL;
382 POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
383 struct lsa_String lsa_account_name;
384 struct samr_Ids user_rids, name_types;
385 struct dom_sid2 *domain_sid = NULL;
386 struct dom_sid2 user_sid;
388 ZERO_STRUCT(connect_handle);
389 ZERO_STRUCT(builtin_handle);
390 ZERO_STRUCT(domain_handle);
391 ZERO_STRUCT(user_handle);
393 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
394 if (!W_ERROR_IS_OK(werr)) {
398 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
400 if (!W_ERROR_IS_OK(werr)) {
404 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
405 SAMR_ACCESS_ENUM_DOMAINS |
406 SAMR_ACCESS_OPEN_DOMAIN,
407 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
411 if (!W_ERROR_IS_OK(werr)) {
415 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
417 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
418 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
420 if (!NT_STATUS_IS_OK(status)) {
421 werr = ntstatus_to_werror(status);
425 init_lsa_String(&lsa_account_name, r->in.user_name);
427 status = rpccli_samr_LookupNames(pipe_cli, ctx,
433 if (!NT_STATUS_IS_OK(status)) {
434 werr = ntstatus_to_werror(status);
438 status = rpccli_samr_OpenUser(pipe_cli, ctx,
440 STD_RIGHT_DELETE_ACCESS,
443 if (!NT_STATUS_IS_OK(status)) {
444 werr = ntstatus_to_werror(status);
448 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
450 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
453 if (!NT_STATUS_IS_OK(status)) {
454 werr = ntstatus_to_werror(status);
458 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
460 if (!NT_STATUS_IS_OK(status)) {
461 werr = ntstatus_to_werror(status);
472 if (is_valid_policy_hnd(&user_handle)) {
473 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
476 if (ctx->disable_policy_handle_cache) {
477 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
478 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
479 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
485 /****************************************************************
486 ****************************************************************/
488 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
489 struct NetUserDel *r)
491 /* for now just talk to local RPC server */
492 if (!r->in.server_name) {
493 r->in.server_name = "localhost";
496 return NetUserDel_r(ctx, r);
499 /****************************************************************
500 ****************************************************************/
502 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
503 struct rpc_pipe_client *pipe_cli,
504 struct policy_handle *domain_handle,
505 struct policy_handle *builtin_handle,
506 const char *user_name,
509 struct samr_UserInfo21 **info21,
510 struct sec_desc_buf **sec_desc)
514 struct policy_handle user_handle;
515 union samr_UserInfo *user_info = NULL;
516 struct samr_RidWithAttributeArray *rid_array = NULL;
517 uint32_t access_mask = SEC_STD_READ_CONTROL |
518 SAMR_USER_ACCESS_GET_ATTRIBUTES |
519 SAMR_USER_ACCESS_GET_NAME_ETC;
521 ZERO_STRUCT(user_handle);
534 return NT_STATUS_INVALID_LEVEL;
541 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
546 if (!NT_STATUS_IS_OK(status)) {
550 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
554 if (!NT_STATUS_IS_OK(status)) {
558 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
562 if (!NT_STATUS_IS_OK(status)) {
567 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
570 if (!NT_STATUS_IS_OK(status)) {
575 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
579 if (!NT_STATUS_IS_OK(status)) {
585 *info21 = &user_info->info21;
588 if (is_valid_policy_hnd(&user_handle)) {
589 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
595 /****************************************************************
596 ****************************************************************/
598 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
599 struct rpc_pipe_client *pipe_cli,
600 struct dom_sid *domain_sid,
601 struct policy_handle *domain_handle,
602 struct policy_handle *builtin_handle,
603 const char *user_name,
607 uint32_t *num_entries)
611 struct samr_UserInfo21 *info21 = NULL;
612 struct sec_desc_buf *sec_desc = NULL;
615 struct USER_INFO_0 info0;
616 struct USER_INFO_10 info10;
617 struct USER_INFO_20 info20;
618 struct USER_INFO_23 info23;
631 return NT_STATUS_INVALID_LEVEL;
635 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
636 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
638 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
639 (struct USER_INFO_0 **)buffer, num_entries);
644 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
653 if (!NT_STATUS_IS_OK(status)) {
659 info10.usri10_name = talloc_strdup(mem_ctx, user_name);
660 NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
662 info10.usri10_comment = talloc_strdup(mem_ctx,
663 info21->description.string);
665 info10.usri10_full_name = talloc_strdup(mem_ctx,
666 info21->full_name.string);
668 info10.usri10_usr_comment = talloc_strdup(mem_ctx,
669 info21->comment.string);
671 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
672 (struct USER_INFO_10 **)buffer, num_entries);
677 info20.usri20_name = talloc_strdup(mem_ctx, user_name);
678 NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
680 info20.usri20_comment = talloc_strdup(mem_ctx,
681 info21->description.string);
683 info20.usri20_full_name = talloc_strdup(mem_ctx,
684 info21->full_name.string);
686 info20.usri20_flags = info21->acct_flags;
687 info20.usri20_user_id = rid;
689 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
690 (struct USER_INFO_20 **)buffer, num_entries);
694 info23.usri23_name = talloc_strdup(mem_ctx, user_name);
695 NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
697 info23.usri23_comment = talloc_strdup(mem_ctx,
698 info21->description.string);
700 info23.usri23_full_name = talloc_strdup(mem_ctx,
701 info21->full_name.string);
703 info23.usri23_flags = info21->acct_flags;
705 if (!sid_compose(&sid, domain_sid, rid)) {
706 return NT_STATUS_NO_MEMORY;
709 info23.usri23_user_sid =
710 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
712 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
713 (struct USER_INFO_23 **)buffer, num_entries);
721 /****************************************************************
722 ****************************************************************/
724 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
725 struct NetUserEnum *r)
727 struct cli_state *cli = NULL;
728 struct rpc_pipe_client *pipe_cli = NULL;
729 struct policy_handle connect_handle;
730 struct dom_sid2 *domain_sid = NULL;
731 struct policy_handle domain_handle;
732 struct samr_SamArray *sam = NULL;
733 uint32_t filter = ACB_NORMAL;
735 uint32_t entries_read = 0;
737 NTSTATUS status = NT_STATUS_OK;
740 ZERO_STRUCT(connect_handle);
741 ZERO_STRUCT(domain_handle);
743 if (!r->out.buffer) {
744 return WERR_INVALID_PARAM;
747 *r->out.buffer = NULL;
748 *r->out.entries_read = 0;
750 switch (r->in.level) {
761 return WERR_NOT_SUPPORTED;
764 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
765 if (!W_ERROR_IS_OK(werr)) {
769 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
771 if (!W_ERROR_IS_OK(werr)) {
775 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
776 SAMR_ACCESS_ENUM_DOMAINS |
777 SAMR_ACCESS_OPEN_DOMAIN,
778 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
779 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
780 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
784 if (!W_ERROR_IS_OK(werr)) {
788 switch (r->in.filter) {
789 case FILTER_NORMAL_ACCOUNT:
792 case FILTER_TEMP_DUPLICATE_ACCOUNT:
793 filter = ACB_TEMPDUP;
795 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
796 filter = ACB_DOMTRUST;
798 case FILTER_WORKSTATION_TRUST_ACCOUNT:
799 filter = ACB_WSTRUST;
801 case FILTER_SERVER_TRUST_ACCOUNT:
802 filter = ACB_SVRTRUST;
808 status = rpccli_samr_EnumDomainUsers(pipe_cli,
816 werr = ntstatus_to_werror(status);
817 if (NT_STATUS_IS_ERR(status)) {
821 for (i=0; i < sam->count; i++) {
823 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
826 NULL, /*&builtin_handle, */
827 sam->entries[i].name.string,
831 r->out.entries_read);
832 if (!NT_STATUS_IS_OK(status)) {
833 werr = ntstatus_to_werror(status);
844 if (NT_STATUS_IS_OK(status) ||
845 NT_STATUS_IS_ERR(status)) {
847 if (ctx->disable_policy_handle_cache) {
848 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
849 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
856 /****************************************************************
857 ****************************************************************/
859 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
860 struct NetUserEnum *r)
862 return WERR_NOT_SUPPORTED;
865 /****************************************************************
866 ****************************************************************/
868 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
869 struct samr_DispInfoGeneral *info,
870 uint32_t *entries_read,
873 struct NET_DISPLAY_USER *user = NULL;
876 user = TALLOC_ZERO_ARRAY(mem_ctx,
877 struct NET_DISPLAY_USER,
879 W_ERROR_HAVE_NO_MEMORY(user);
881 for (i = 0; i < info->count; i++) {
882 user[i].usri1_name = talloc_strdup(mem_ctx,
883 info->entries[i].account_name.string);
884 user[i].usri1_comment = talloc_strdup(mem_ctx,
885 info->entries[i].description.string);
886 user[i].usri1_flags =
887 info->entries[i].acct_flags;
888 user[i].usri1_full_name = talloc_strdup(mem_ctx,
889 info->entries[i].full_name.string);
890 user[i].usri1_user_id =
891 info->entries[i].rid;
892 user[i].usri1_next_index =
893 info->entries[i].idx;
895 if (!user[i].usri1_name) {
900 *buffer = talloc_memdup(mem_ctx, user,
901 sizeof(struct NET_DISPLAY_USER) * info->count);
902 W_ERROR_HAVE_NO_MEMORY(*buffer);
904 *entries_read = info->count;
909 /****************************************************************
910 ****************************************************************/
912 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
913 struct samr_DispInfoFull *info,
914 uint32_t *entries_read,
917 struct NET_DISPLAY_MACHINE *machine = NULL;
920 machine = TALLOC_ZERO_ARRAY(mem_ctx,
921 struct NET_DISPLAY_MACHINE,
923 W_ERROR_HAVE_NO_MEMORY(machine);
925 for (i = 0; i < info->count; i++) {
926 machine[i].usri2_name = talloc_strdup(mem_ctx,
927 info->entries[i].account_name.string);
928 machine[i].usri2_comment = talloc_strdup(mem_ctx,
929 info->entries[i].description.string);
930 machine[i].usri2_flags =
931 info->entries[i].acct_flags;
932 machine[i].usri2_user_id =
933 info->entries[i].rid;
934 machine[i].usri2_next_index =
935 info->entries[i].idx;
937 if (!machine[i].usri2_name) {
942 *buffer = talloc_memdup(mem_ctx, machine,
943 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
944 W_ERROR_HAVE_NO_MEMORY(*buffer);
946 *entries_read = info->count;
951 /****************************************************************
952 ****************************************************************/
954 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
955 struct samr_DispInfoFullGroups *info,
956 uint32_t *entries_read,
959 struct NET_DISPLAY_GROUP *group = NULL;
962 group = TALLOC_ZERO_ARRAY(mem_ctx,
963 struct NET_DISPLAY_GROUP,
965 W_ERROR_HAVE_NO_MEMORY(group);
967 for (i = 0; i < info->count; i++) {
968 group[i].grpi3_name = talloc_strdup(mem_ctx,
969 info->entries[i].account_name.string);
970 group[i].grpi3_comment = talloc_strdup(mem_ctx,
971 info->entries[i].description.string);
972 group[i].grpi3_group_id =
973 info->entries[i].rid;
974 group[i].grpi3_attributes =
975 info->entries[i].acct_flags;
976 group[i].grpi3_next_index =
977 info->entries[i].idx;
979 if (!group[i].grpi3_name) {
984 *buffer = talloc_memdup(mem_ctx, group,
985 sizeof(struct NET_DISPLAY_GROUP) * info->count);
986 W_ERROR_HAVE_NO_MEMORY(*buffer);
988 *entries_read = info->count;
994 /****************************************************************
995 ****************************************************************/
997 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
998 union samr_DispInfo *info,
1000 uint32_t *entries_read,
1005 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1010 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1015 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1020 return WERR_UNKNOWN_LEVEL;
1026 /****************************************************************
1027 ****************************************************************/
1029 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1030 struct NetQueryDisplayInformation *r)
1032 struct cli_state *cli = NULL;
1033 struct rpc_pipe_client *pipe_cli = NULL;
1034 struct policy_handle connect_handle;
1035 struct dom_sid2 *domain_sid = NULL;
1036 struct policy_handle domain_handle;
1037 union samr_DispInfo info;
1039 uint32_t total_size = 0;
1040 uint32_t returned_size = 0;
1042 NTSTATUS status = NT_STATUS_OK;
1045 ZERO_STRUCT(connect_handle);
1046 ZERO_STRUCT(domain_handle);
1048 switch (r->in.level) {
1054 return WERR_UNKNOWN_LEVEL;
1057 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1058 if (!W_ERROR_IS_OK(werr)) {
1062 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1064 if (!W_ERROR_IS_OK(werr)) {
1068 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1069 SAMR_ACCESS_ENUM_DOMAINS |
1070 SAMR_ACCESS_OPEN_DOMAIN,
1071 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1072 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1073 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1077 if (!W_ERROR_IS_OK(werr)) {
1081 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1086 r->in.entries_requested,
1091 if (!NT_STATUS_IS_OK(status)) {
1092 werr = ntstatus_to_werror(status);
1096 werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1098 r->out.entries_read,
1106 if (NT_STATUS_IS_OK(status) ||
1107 NT_STATUS_IS_ERR(status)) {
1109 if (ctx->disable_policy_handle_cache) {
1110 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1111 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1119 /****************************************************************
1120 ****************************************************************/
1123 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1124 struct NetQueryDisplayInformation *r)
1126 return WERR_NOT_SUPPORTED;
1129 /****************************************************************
1130 ****************************************************************/
1132 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1133 struct NetUserChangePassword *r)
1135 return WERR_NOT_SUPPORTED;
1138 /****************************************************************
1139 ****************************************************************/
1141 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1142 struct NetUserChangePassword *r)
1144 return WERR_NOT_SUPPORTED;
1147 /****************************************************************
1148 ****************************************************************/
1150 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1151 struct NetUserGetInfo *r)
1153 struct cli_state *cli = NULL;
1154 struct rpc_pipe_client *pipe_cli = NULL;
1158 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1159 struct lsa_String lsa_account_name;
1160 struct dom_sid2 *domain_sid = NULL;
1161 struct samr_Ids user_rids, name_types;
1162 uint32_t num_entries = 0;
1164 ZERO_STRUCT(connect_handle);
1165 ZERO_STRUCT(domain_handle);
1166 ZERO_STRUCT(builtin_handle);
1167 ZERO_STRUCT(user_handle);
1169 if (!r->out.buffer) {
1170 return WERR_INVALID_PARAM;
1173 switch (r->in.level) {
1181 werr = WERR_NOT_SUPPORTED;
1185 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1186 if (!W_ERROR_IS_OK(werr)) {
1190 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1192 if (!W_ERROR_IS_OK(werr)) {
1196 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1197 SAMR_ACCESS_ENUM_DOMAINS |
1198 SAMR_ACCESS_OPEN_DOMAIN,
1199 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1203 if (!W_ERROR_IS_OK(werr)) {
1207 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1208 SAMR_ACCESS_ENUM_DOMAINS |
1209 SAMR_ACCESS_OPEN_DOMAIN,
1210 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1211 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1214 if (!W_ERROR_IS_OK(werr)) {
1218 init_lsa_String(&lsa_account_name, r->in.user_name);
1220 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1226 if (!NT_STATUS_IS_OK(status)) {
1227 werr = ntstatus_to_werror(status);
1231 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1240 if (!NT_STATUS_IS_OK(status)) {
1241 werr = ntstatus_to_werror(status);
1250 if (is_valid_policy_hnd(&user_handle)) {
1251 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1254 if (ctx->disable_policy_handle_cache) {
1255 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1256 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1262 /****************************************************************
1263 ****************************************************************/
1265 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1266 struct NetUserGetInfo *r)
1268 return WERR_NOT_SUPPORTED;
1271 /****************************************************************
1272 ****************************************************************/
1274 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1275 struct NetUserSetInfo *r)
1277 struct cli_state *cli = NULL;
1278 struct rpc_pipe_client *pipe_cli = NULL;
1282 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1283 struct lsa_String lsa_account_name;
1284 struct dom_sid2 *domain_sid = NULL;
1285 struct samr_Ids user_rids, name_types;
1286 union samr_UserInfo user_info;
1288 struct USER_INFO_X uX;
1290 ZERO_STRUCT(connect_handle);
1291 ZERO_STRUCT(domain_handle);
1292 ZERO_STRUCT(builtin_handle);
1293 ZERO_STRUCT(user_handle);
1295 if (!r->in.buffer) {
1296 return WERR_INVALID_PARAM;
1299 switch (r->in.level) {
1304 werr = WERR_NOT_SUPPORTED;
1308 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
1309 if (!W_ERROR_IS_OK(werr)) {
1313 werr = libnetapi_open_pipe(ctx, cli, &ndr_table_samr.syntax_id,
1315 if (!W_ERROR_IS_OK(werr)) {
1319 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1320 SAMR_ACCESS_ENUM_DOMAINS |
1321 SAMR_ACCESS_OPEN_DOMAIN,
1322 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1323 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1327 if (!W_ERROR_IS_OK(werr)) {
1331 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1332 SAMR_ACCESS_ENUM_DOMAINS |
1333 SAMR_ACCESS_OPEN_DOMAIN,
1334 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1335 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1338 if (!W_ERROR_IS_OK(werr)) {
1342 init_lsa_String(&lsa_account_name, r->in.user_name);
1344 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1350 if (!NT_STATUS_IS_OK(status)) {
1351 werr = ntstatus_to_werror(status);
1355 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1357 SAMR_USER_ACCESS_SET_ATTRIBUTES,
1360 if (!NT_STATUS_IS_OK(status)) {
1361 werr = ntstatus_to_werror(status);
1365 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 werr = ntstatus_to_werror(status);
1371 convert_USER_INFO_X_to_samr_user_info21(&uX, &user_info.info21);
1373 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
1377 if (!NT_STATUS_IS_OK(status)) {
1378 werr = ntstatus_to_werror(status);
1389 if (is_valid_policy_hnd(&user_handle)) {
1390 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1393 if (ctx->disable_policy_handle_cache) {
1394 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1395 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1396 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1402 /****************************************************************
1403 ****************************************************************/
1405 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1406 struct NetUserSetInfo *r)
1408 return WERR_NOT_SUPPORTED;