ctdb-server: Clean up connection tracking functions
[samba4-gss.git] / source3 / lib / netapi / user.c
blobd3d87be8c514810f5016625202c62a9227122c10
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi User Support
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/>.
20 #include "includes.h"
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;
43 NTTIME password_age;
45 ZERO_STRUCTP(info21);
46 ZERO_STRUCT(zero_logon_hours);
47 ZERO_STRUCT(zero_parameters);
49 if (infoX->usriX_flags) {
50 fields_present |= SAMR_FIELD_ACCT_FLAGS;
52 if (infoX->usriX_name) {
53 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
55 if (infoX->usriX_password) {
56 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
58 if (infoX->usriX_flags) {
59 fields_present |= SAMR_FIELD_ACCT_FLAGS;
61 if (infoX->usriX_home_dir) {
62 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
64 if (infoX->usriX_script_path) {
65 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
67 if (infoX->usriX_comment) {
68 fields_present |= SAMR_FIELD_DESCRIPTION;
70 if (infoX->usriX_password_age) {
71 fields_present |= SAMR_FIELD_EXPIRED_FLAG;
73 if (infoX->usriX_full_name) {
74 fields_present |= SAMR_FIELD_FULL_NAME;
76 if (infoX->usriX_usr_comment) {
77 fields_present |= SAMR_FIELD_COMMENT;
79 if (infoX->usriX_profile) {
80 fields_present |= SAMR_FIELD_PROFILE_PATH;
82 if (infoX->usriX_home_dir_drive) {
83 fields_present |= SAMR_FIELD_HOME_DRIVE;
85 if (infoX->usriX_primary_group_id) {
86 fields_present |= SAMR_FIELD_PRIMARY_GID;
88 if (infoX->usriX_country_code) {
89 fields_present |= SAMR_FIELD_COUNTRY_CODE;
91 if (infoX->usriX_workstations) {
92 fields_present |= SAMR_FIELD_WORKSTATIONS;
95 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
97 /* TODO: infoX->usriX_priv */
99 info21->last_logon = 0;
100 info21->last_logoff = 0;
101 info21->last_password_change = 0;
102 info21->acct_expiry = 0;
103 info21->allow_password_change = 0;
104 info21->force_password_change = 0;
105 info21->account_name.string = infoX->usriX_name;
106 info21->full_name.string = infoX->usriX_full_name;
107 info21->home_directory.string = infoX->usriX_home_dir;
108 info21->home_drive.string = infoX->usriX_home_dir_drive;
109 info21->logon_script.string = infoX->usriX_script_path;
110 info21->profile_path.string = infoX->usriX_profile;
111 info21->description.string = infoX->usriX_comment;
112 info21->workstations.string = infoX->usriX_workstations;
113 info21->comment.string = infoX->usriX_usr_comment;
114 info21->parameters = zero_parameters;
115 info21->lm_owf_password = zero_parameters;
116 info21->nt_owf_password = zero_parameters;
117 info21->private_data.string = NULL;
118 info21->buf_count = 0;
119 info21->buffer = NULL;
120 info21->rid = infoX->usriX_user_id;
121 info21->primary_gid = infoX->usriX_primary_group_id;
122 info21->acct_flags = infoX->usriX_flags;
123 info21->fields_present = fields_present;
124 info21->logon_hours = zero_logon_hours;
125 info21->bad_password_count = infoX->usriX_bad_pw_count;
126 info21->logon_count = infoX->usriX_num_logons;
127 info21->country_code = infoX->usriX_country_code;
128 info21->code_page = infoX->usriX_code_page;
129 info21->lm_password_set = 0;
130 info21->nt_password_set = 0;
131 info21->password_expired = infoX->usriX_password_expired;
132 info21->private_data_sensitive = 0;
135 /****************************************************************
136 ****************************************************************/
138 static NTSTATUS construct_USER_INFO_X(uint32_t level,
139 uint8_t *buffer,
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;
162 ZERO_STRUCTP(uX);
164 switch (level) {
165 case 0:
166 u0 = (struct USER_INFO_0 *)buffer;
167 uX->usriX_name = u0->usri0_name;
168 break;
169 case 1:
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;
179 break;
180 case 2:
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;
206 break;
207 case 3:
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;
237 break;
238 case 1003:
239 u1003 = (struct USER_INFO_1003 *)buffer;
240 uX->usriX_password = u1003->usri1003_password;
241 break;
242 case 1006:
243 u1006 = (struct USER_INFO_1006 *)buffer;
244 uX->usriX_home_dir = u1006->usri1006_home_dir;
245 break;
246 case 1007:
247 u1007 = (struct USER_INFO_1007 *)buffer;
248 uX->usriX_comment = u1007->usri1007_comment;
249 break;
250 case 1009:
251 u1009 = (struct USER_INFO_1009 *)buffer;
252 uX->usriX_script_path = u1009->usri1009_script_path;
253 break;
254 case 1011:
255 u1011 = (struct USER_INFO_1011 *)buffer;
256 uX->usriX_full_name = u1011->usri1011_full_name;
257 break;
258 case 1012:
259 u1012 = (struct USER_INFO_1012 *)buffer;
260 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
261 break;
262 case 1014:
263 u1014 = (struct USER_INFO_1014 *)buffer;
264 uX->usriX_workstations = u1014->usri1014_workstations;
265 break;
266 case 1024:
267 u1024 = (struct USER_INFO_1024 *)buffer;
268 uX->usriX_country_code = u1024->usri1024_country_code;
269 break;
270 case 1051:
271 u1051 = (struct USER_INFO_1051 *)buffer;
272 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
273 break;
274 case 1052:
275 u1052 = (struct USER_INFO_1052 *)buffer;
276 uX->usriX_profile = u1052->usri1052_profile;
277 break;
278 case 1053:
279 u1053 = (struct USER_INFO_1053 *)buffer;
280 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
281 break;
282 case 4:
283 default:
284 return NT_STATUS_INVALID_INFO_CLASS;
287 return NT_STATUS_OK;
290 /****************************************************************
291 ****************************************************************/
293 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *mem_ctx,
294 struct rpc_pipe_client *pipe_cli,
295 DATA_BLOB *session_key,
296 struct policy_handle *user_handle,
297 struct USER_INFO_X *uX)
299 union samr_UserInfo user_info;
300 struct samr_UserInfo21 info21;
301 NTSTATUS status, result;
302 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
304 if (!uX) {
305 return NT_STATUS_INVALID_PARAMETER;
308 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
310 ZERO_STRUCT(user_info);
312 if (uX->usriX_password) {
314 user_info.info25.info = info21;
316 status = init_samr_CryptPasswordEx(uX->usriX_password,
317 session_key,
318 &user_info.info25.password);
319 if (!NT_STATUS_IS_OK(status)) {
320 return status;
323 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
324 user_handle,
326 &user_info,
327 &result);
328 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
330 user_info.info23.info = info21;
332 status = init_samr_CryptPassword(uX->usriX_password,
333 session_key,
334 &user_info.info23.password);
335 if (!NT_STATUS_IS_OK(status)) {
336 return status;
339 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
340 user_handle,
342 &user_info,
343 &result);
344 if (!NT_STATUS_IS_OK(status)) {
345 return status;
349 if (!NT_STATUS_IS_OK(status)) {
350 return status;
352 } else {
354 user_info.info21 = info21;
356 status = dcerpc_samr_SetUserInfo(b, mem_ctx,
357 user_handle,
359 &user_info,
360 &result);
361 if (!NT_STATUS_IS_OK(status)) {
362 return status;
366 return result;
369 /****************************************************************
370 ****************************************************************/
372 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
373 struct NetUserAdd *r)
375 struct rpc_pipe_client *pipe_cli = NULL;
376 NTSTATUS status, result;
377 WERROR werr;
378 struct policy_handle connect_handle, domain_handle, user_handle;
379 struct lsa_String lsa_account_name;
380 struct dom_sid2 *domain_sid = NULL;
381 union samr_UserInfo *user_info = NULL;
382 struct samr_PwInfo pw_info;
383 uint32_t access_granted = 0;
384 uint32_t rid = 0;
385 struct USER_INFO_X uX;
386 struct dcerpc_binding_handle *b = NULL;
387 DATA_BLOB session_key;
389 ZERO_STRUCT(connect_handle);
390 ZERO_STRUCT(domain_handle);
391 ZERO_STRUCT(user_handle);
393 if (!r->in.buffer) {
394 return WERR_INVALID_PARAMETER;
397 switch (r->in.level) {
398 case 1:
399 break;
400 case 2:
401 case 3:
402 case 4:
403 default:
404 werr = WERR_NOT_SUPPORTED;
405 goto done;
408 werr = libnetapi_open_pipe(ctx, r->in.server_name,
409 &ndr_table_samr,
410 &pipe_cli);
411 if (!W_ERROR_IS_OK(werr)) {
412 goto done;
415 b = pipe_cli->binding_handle;
417 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
418 if (!NT_STATUS_IS_OK(status)) {
419 werr = ntstatus_to_werror(status);
420 goto done;
423 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
424 SAMR_ACCESS_ENUM_DOMAINS |
425 SAMR_ACCESS_LOOKUP_DOMAIN,
426 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
427 SAMR_DOMAIN_ACCESS_CREATE_USER |
428 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
429 &connect_handle,
430 &domain_handle,
431 &domain_sid);
432 if (!W_ERROR_IS_OK(werr)) {
433 goto done;
436 init_lsa_String(&lsa_account_name, uX.usriX_name);
438 status = dcerpc_samr_CreateUser2(b, talloc_tos(),
439 &domain_handle,
440 &lsa_account_name,
441 ACB_NORMAL,
442 SEC_STD_WRITE_DAC |
443 SEC_STD_DELETE |
444 SAMR_USER_ACCESS_SET_PASSWORD |
445 SAMR_USER_ACCESS_SET_ATTRIBUTES |
446 SAMR_USER_ACCESS_GET_ATTRIBUTES,
447 &user_handle,
448 &access_granted,
449 &rid,
450 &result);
451 if (any_nt_status_not_ok(status, result, &status)) {
452 werr = ntstatus_to_werror(status);
453 goto done;
456 status = dcerpc_samr_QueryUserInfo(b, talloc_tos(),
457 &user_handle,
459 &user_info,
460 &result);
461 if (any_nt_status_not_ok(status, result, &status)) {
462 werr = ntstatus_to_werror(status);
463 goto done;
466 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
467 werr = WERR_INVALID_PARAMETER;
468 goto done;
471 status = dcerpc_samr_GetUserPwInfo(b, talloc_tos(),
472 &user_handle,
473 &pw_info,
474 &result);
475 if (any_nt_status_not_ok(status, result, &status)) {
476 werr = ntstatus_to_werror(status);
477 goto done;
480 status = dcerpc_binding_handle_transport_session_key(
481 b, talloc_tos(), &session_key);
482 if (!NT_STATUS_IS_OK(status)) {
483 werr = ntstatus_to_werror(status);
484 goto done;
487 uX.usriX_flags |= ACB_NORMAL;
489 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
490 &session_key,
491 &user_handle,
492 &uX);
493 if (!NT_STATUS_IS_OK(status)) {
494 werr = ntstatus_to_werror(status);
495 goto failed;
498 werr = WERR_OK;
499 goto done;
501 failed:
502 dcerpc_samr_DeleteUser(b, talloc_tos(),
503 &user_handle,
504 &result);
506 done:
507 if (is_valid_policy_hnd(&user_handle) && b) {
508 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
511 if (ctx->disable_policy_handle_cache) {
512 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
513 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
516 return werr;
519 /****************************************************************
520 ****************************************************************/
522 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
523 struct NetUserAdd *r)
525 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
528 /****************************************************************
529 ****************************************************************/
531 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
532 struct NetUserDel *r)
534 struct rpc_pipe_client *pipe_cli = NULL;
535 NTSTATUS status, result;
536 WERROR werr;
537 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
538 struct lsa_String lsa_account_name;
539 struct samr_Ids user_rids, name_types;
540 struct dom_sid2 *domain_sid = NULL;
541 struct dom_sid2 user_sid;
542 struct dcerpc_binding_handle *b = NULL;
544 ZERO_STRUCT(connect_handle);
545 ZERO_STRUCT(builtin_handle);
546 ZERO_STRUCT(domain_handle);
547 ZERO_STRUCT(user_handle);
549 werr = libnetapi_open_pipe(ctx, r->in.server_name,
550 &ndr_table_samr,
551 &pipe_cli);
553 if (!W_ERROR_IS_OK(werr)) {
554 goto done;
557 b = pipe_cli->binding_handle;
559 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
560 SAMR_ACCESS_ENUM_DOMAINS |
561 SAMR_ACCESS_LOOKUP_DOMAIN,
562 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
563 &connect_handle,
564 &domain_handle,
565 &domain_sid);
566 if (!W_ERROR_IS_OK(werr)) {
567 goto done;
570 status = dcerpc_samr_OpenDomain(b, talloc_tos(),
571 &connect_handle,
572 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
573 discard_const_p(struct dom_sid, &global_sid_Builtin),
574 &builtin_handle,
575 &result);
576 if (any_nt_status_not_ok(status, result, &status)) {
577 werr = ntstatus_to_werror(status);
578 goto done;
581 init_lsa_String(&lsa_account_name, r->in.user_name);
583 status = dcerpc_samr_LookupNames(b, talloc_tos(),
584 &domain_handle,
586 &lsa_account_name,
587 &user_rids,
588 &name_types,
589 &result);
590 if (any_nt_status_not_ok(status, result, &status)) {
591 werr = ntstatus_to_werror(status);
592 goto done;
594 if (user_rids.count != 1) {
595 werr = WERR_BAD_NET_RESP;
596 goto done;
598 if (name_types.count != 1) {
599 werr = WERR_BAD_NET_RESP;
600 goto done;
603 status = dcerpc_samr_OpenUser(b, talloc_tos(),
604 &domain_handle,
605 SEC_STD_DELETE,
606 user_rids.ids[0],
607 &user_handle,
608 &result);
609 if (any_nt_status_not_ok(status, result, &status)) {
610 werr = ntstatus_to_werror(status);
611 goto done;
614 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
616 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, talloc_tos(),
617 &builtin_handle,
618 &user_sid,
619 &result);
620 if (any_nt_status_not_ok(status, result, &status)) {
621 werr = ntstatus_to_werror(status);
622 goto done;
625 status = dcerpc_samr_DeleteUser(b, talloc_tos(),
626 &user_handle,
627 &result);
628 if (any_nt_status_not_ok(status, result, &status)) {
629 werr = ntstatus_to_werror(status);
630 goto done;
633 werr = WERR_OK;
635 done:
636 if (is_valid_policy_hnd(&user_handle)) {
637 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
640 if (ctx->disable_policy_handle_cache) {
641 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
642 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
643 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
646 return werr;
649 /****************************************************************
650 ****************************************************************/
652 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
653 struct NetUserDel *r)
655 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
658 /****************************************************************
659 ****************************************************************/
661 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
662 struct rpc_pipe_client *pipe_cli,
663 struct policy_handle *domain_handle,
664 struct policy_handle *builtin_handle,
665 const char *user_name,
666 const struct dom_sid *domain_sid,
667 uint32_t rid,
668 uint32_t level,
669 struct samr_UserInfo21 **info21,
670 struct sec_desc_buf **sec_desc,
671 uint32_t *auth_flag_p)
673 NTSTATUS status, result;
675 struct policy_handle user_handle;
676 union samr_UserInfo *user_info = NULL;
677 struct samr_RidWithAttributeArray *rid_array = NULL;
678 uint32_t access_mask = SEC_STD_READ_CONTROL |
679 SAMR_USER_ACCESS_GET_ATTRIBUTES |
680 SAMR_USER_ACCESS_GET_NAME_ETC;
681 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
683 ZERO_STRUCT(user_handle);
685 switch (level) {
686 case 0:
687 break;
688 case 1:
689 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
690 SAMR_USER_ACCESS_GET_GROUPS;
691 break;
692 case 2:
693 case 3:
694 case 4:
695 case 11:
696 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
697 SAMR_USER_ACCESS_GET_GROUPS |
698 SAMR_USER_ACCESS_GET_LOCALE;
699 break;
700 case 10:
701 case 20:
702 case 23:
703 break;
704 default:
705 return NT_STATUS_INVALID_LEVEL;
708 if (level == 0) {
709 return NT_STATUS_OK;
712 status = dcerpc_samr_OpenUser(b, mem_ctx,
713 domain_handle,
714 access_mask,
715 rid,
716 &user_handle,
717 &result);
718 if (any_nt_status_not_ok(status, result, &status)) {
719 goto done;
722 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
723 &user_handle,
725 &user_info,
726 &result);
727 if (any_nt_status_not_ok(status, result, &status)) {
728 goto done;
731 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
732 &user_handle,
733 SECINFO_DACL,
734 sec_desc,
735 &result);
736 if (any_nt_status_not_ok(status, result, &status)) {
737 goto done;
740 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
742 struct lsa_SidArray sid_array;
743 struct samr_Ids alias_rids;
744 int i;
745 uint32_t auth_flag = 0;
746 struct dom_sid sid;
748 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
749 &user_handle,
750 &rid_array,
751 &result);
752 if (any_nt_status_not_ok(status, result, &status)) {
753 goto done;
756 sid_array.num_sids = rid_array->count + 1;
757 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
758 sid_array.num_sids);
759 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
761 for (i=0; i<rid_array->count; i++) {
762 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
763 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
764 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
767 sid_compose(&sid, domain_sid, rid);
768 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
769 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
771 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
772 builtin_handle,
773 &sid_array,
774 &alias_rids,
775 &result);
776 if (any_nt_status_not_ok(status, result, &status)) {
777 goto done;
780 for (i=0; i<alias_rids.count; i++) {
781 switch (alias_rids.ids[i]) {
782 case 550: /* Print Operators */
783 auth_flag |= AF_OP_PRINT;
784 break;
785 case 549: /* Server Operators */
786 auth_flag |= AF_OP_SERVER;
787 break;
788 case 548: /* Account Operators */
789 auth_flag |= AF_OP_ACCOUNTS;
790 break;
791 default:
792 break;
796 if (auth_flag_p) {
797 *auth_flag_p = auth_flag;
801 *info21 = &user_info->info21;
803 done:
804 if (is_valid_policy_hnd(&user_handle)) {
805 dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
808 return status;
811 /****************************************************************
812 ****************************************************************/
814 static uint32_t samr_rid_to_priv_level(uint32_t rid)
816 switch (rid) {
817 case DOMAIN_RID_ADMINISTRATOR:
818 return USER_PRIV_ADMIN;
819 case DOMAIN_RID_GUEST:
820 return USER_PRIV_GUEST;
821 default:
822 return USER_PRIV_USER;
826 /****************************************************************
827 ****************************************************************/
829 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
831 uint32_t fl = UF_SCRIPT; /* god knows why */
833 fl |= ds_acb2uf(acb);
835 return fl;
838 /****************************************************************
839 ****************************************************************/
841 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
842 const struct samr_UserInfo21 *i21,
843 struct USER_INFO_1 *i)
845 ZERO_STRUCTP(i);
846 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
847 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
848 i->usri1_password = NULL;
849 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
850 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
851 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
852 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
853 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
854 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
856 return NT_STATUS_OK;
859 /****************************************************************
860 ****************************************************************/
862 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
863 const struct samr_UserInfo21 *i21,
864 uint32_t auth_flag,
865 struct USER_INFO_2 *i)
867 ZERO_STRUCTP(i);
869 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
870 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
871 i->usri2_password = NULL;
872 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
873 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
874 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
875 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
876 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
877 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
878 i->usri2_auth_flags = auth_flag;
879 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
880 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
881 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
882 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
883 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
884 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
885 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
886 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
887 i->usri2_units_per_week = i21->logon_hours.units_per_week;
888 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
889 i->usri2_bad_pw_count = i21->bad_password_count;
890 i->usri2_num_logons = i21->logon_count;
891 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
892 i->usri2_country_code = i21->country_code;
893 i->usri2_code_page = i21->code_page;
895 return NT_STATUS_OK;
898 /****************************************************************
899 ****************************************************************/
901 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
902 const struct samr_UserInfo21 *i21,
903 uint32_t auth_flag,
904 struct USER_INFO_3 *i)
906 ZERO_STRUCTP(i);
908 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
909 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
910 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
911 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
912 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
913 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
914 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
915 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
916 i->usri3_auth_flags = auth_flag;
917 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
918 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
919 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
920 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
921 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
922 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
923 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
924 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
925 i->usri3_units_per_week = i21->logon_hours.units_per_week;
926 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
927 i->usri3_bad_pw_count = i21->bad_password_count;
928 i->usri3_num_logons = i21->logon_count;
929 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
930 i->usri3_country_code = i21->country_code;
931 i->usri3_code_page = i21->code_page;
932 i->usri3_user_id = i21->rid;
933 i->usri3_primary_group_id = i21->primary_gid;
934 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
935 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
936 i->usri3_password_expired = i21->password_expired;
938 return NT_STATUS_OK;
941 /****************************************************************
942 ****************************************************************/
944 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
945 const struct samr_UserInfo21 *i21,
946 uint32_t auth_flag,
947 struct dom_sid *domain_sid,
948 struct USER_INFO_4 *i)
950 struct dom_sid sid;
952 ZERO_STRUCTP(i);
954 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
955 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
956 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
957 i->usri4_password = NULL;
958 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
959 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
960 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
961 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
962 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
963 i->usri4_auth_flags = auth_flag;
964 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
965 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
966 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
967 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
968 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
969 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
970 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
971 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
972 i->usri4_units_per_week = i21->logon_hours.units_per_week;
973 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
974 i->usri4_bad_pw_count = i21->bad_password_count;
975 i->usri4_num_logons = i21->logon_count;
976 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
977 i->usri4_country_code = i21->country_code;
978 i->usri4_code_page = i21->code_page;
979 if (!sid_compose(&sid, domain_sid, i21->rid)) {
980 return NT_STATUS_NO_MEMORY;
982 i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
983 i->usri4_primary_group_id = i21->primary_gid;
984 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
985 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
986 i->usri4_password_expired = i21->password_expired;
988 return NT_STATUS_OK;
991 /****************************************************************
992 ****************************************************************/
994 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
995 const struct samr_UserInfo21 *i21,
996 struct USER_INFO_10 *i)
998 ZERO_STRUCTP(i);
1000 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
1001 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
1002 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
1003 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1004 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1006 return NT_STATUS_OK;
1009 /****************************************************************
1010 ****************************************************************/
1012 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
1013 const struct samr_UserInfo21 *i21,
1014 uint32_t auth_flag,
1015 struct USER_INFO_11 *i)
1017 ZERO_STRUCTP(i);
1019 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
1020 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
1021 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
1022 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1023 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1024 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
1025 i->usri11_auth_flags = auth_flag;
1026 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1027 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1028 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1029 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
1030 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
1031 i->usri11_bad_pw_count = i21->bad_password_count;
1032 i->usri11_num_logons = i21->logon_count;
1033 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1034 i->usri11_country_code = i21->country_code;
1035 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1036 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1037 i->usri11_units_per_week = i21->logon_hours.units_per_week;
1038 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1039 i->usri11_code_page = i21->code_page;
1041 return NT_STATUS_OK;
1044 /****************************************************************
1045 ****************************************************************/
1047 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
1048 const struct samr_UserInfo21 *i21,
1049 struct USER_INFO_20 *i)
1051 ZERO_STRUCTP(i);
1053 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1054 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1055 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1056 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1057 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1058 i->usri20_user_id = i21->rid;
1060 return NT_STATUS_OK;
1063 /****************************************************************
1064 ****************************************************************/
1066 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1067 const struct samr_UserInfo21 *i21,
1068 struct dom_sid *domain_sid,
1069 struct USER_INFO_23 *i)
1071 struct dom_sid sid;
1073 ZERO_STRUCTP(i);
1075 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1076 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1077 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1078 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1079 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1080 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1081 return NT_STATUS_NO_MEMORY;
1083 i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1085 return NT_STATUS_OK;
1088 /****************************************************************
1089 ****************************************************************/
1091 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1092 struct rpc_pipe_client *pipe_cli,
1093 struct dom_sid *domain_sid,
1094 struct policy_handle *domain_handle,
1095 struct policy_handle *builtin_handle,
1096 const char *user_name,
1097 uint32_t rid,
1098 uint32_t level,
1099 uint8_t **buffer,
1100 uint32_t *num_entries)
1102 NTSTATUS status;
1104 struct samr_UserInfo21 *info21 = NULL;
1105 struct sec_desc_buf *sec_desc = NULL;
1106 uint32_t auth_flag = 0;
1108 struct USER_INFO_0 info0;
1109 struct USER_INFO_1 info1;
1110 struct USER_INFO_2 info2;
1111 struct USER_INFO_3 info3;
1112 struct USER_INFO_4 info4;
1113 struct USER_INFO_10 info10;
1114 struct USER_INFO_11 info11;
1115 struct USER_INFO_20 info20;
1116 struct USER_INFO_23 info23;
1118 switch (level) {
1119 case 0:
1120 case 1:
1121 case 2:
1122 case 3:
1123 case 4:
1124 case 10:
1125 case 11:
1126 case 20:
1127 case 23:
1128 break;
1129 default:
1130 return NT_STATUS_INVALID_LEVEL;
1133 if (level == 0) {
1134 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1135 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1137 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1138 (struct USER_INFO_0 **)buffer, num_entries);
1140 return NT_STATUS_OK;
1143 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1144 domain_handle,
1145 builtin_handle,
1146 user_name,
1147 domain_sid,
1148 rid,
1149 level,
1150 &info21,
1151 &sec_desc,
1152 &auth_flag);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 goto done;
1158 switch (level) {
1159 case 1:
1160 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1161 NT_STATUS_NOT_OK_RETURN(status);
1163 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1164 (struct USER_INFO_1 **)buffer, num_entries);
1166 break;
1167 case 2:
1168 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1169 NT_STATUS_NOT_OK_RETURN(status);
1171 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1172 (struct USER_INFO_2 **)buffer, num_entries);
1174 break;
1175 case 3:
1176 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1177 NT_STATUS_NOT_OK_RETURN(status);
1179 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1180 (struct USER_INFO_3 **)buffer, num_entries);
1182 break;
1183 case 4:
1184 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1185 NT_STATUS_NOT_OK_RETURN(status);
1187 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1188 (struct USER_INFO_4 **)buffer, num_entries);
1190 break;
1191 case 10:
1192 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1193 NT_STATUS_NOT_OK_RETURN(status);
1195 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1196 (struct USER_INFO_10 **)buffer, num_entries);
1198 break;
1199 case 11:
1200 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1201 NT_STATUS_NOT_OK_RETURN(status);
1203 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1204 (struct USER_INFO_11 **)buffer, num_entries);
1206 break;
1207 case 20:
1208 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1209 NT_STATUS_NOT_OK_RETURN(status);
1211 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1212 (struct USER_INFO_20 **)buffer, num_entries);
1214 break;
1215 case 23:
1216 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1217 NT_STATUS_NOT_OK_RETURN(status);
1219 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1220 (struct USER_INFO_23 **)buffer, num_entries);
1221 break;
1222 default:
1223 return NT_STATUS_INVALID_LEVEL;
1226 done:
1227 return status;
1230 /****************************************************************
1231 ****************************************************************/
1233 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1234 struct NetUserEnum *r)
1236 struct rpc_pipe_client *pipe_cli = NULL;
1237 struct policy_handle connect_handle;
1238 struct dom_sid2 *domain_sid = NULL;
1239 struct policy_handle domain_handle, builtin_handle;
1240 struct samr_SamArray *sam = NULL;
1241 uint32_t filter = ACB_NORMAL;
1242 int i;
1243 uint32_t entries_read = 0;
1245 NTSTATUS status;
1246 NTSTATUS result = NT_STATUS_OK;
1247 WERROR werr;
1248 struct dcerpc_binding_handle *b = NULL;
1250 ZERO_STRUCT(connect_handle);
1251 ZERO_STRUCT(domain_handle);
1252 ZERO_STRUCT(builtin_handle);
1254 if (!r->out.buffer) {
1255 return WERR_INVALID_PARAMETER;
1258 *r->out.buffer = NULL;
1259 *r->out.entries_read = 0;
1261 switch (r->in.level) {
1262 case 0:
1263 case 1:
1264 case 2:
1265 case 3:
1266 case 4:
1267 case 10:
1268 case 11:
1269 case 20:
1270 case 23:
1271 break;
1272 default:
1273 return WERR_INVALID_LEVEL;
1276 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1277 &ndr_table_samr,
1278 &pipe_cli);
1279 if (!W_ERROR_IS_OK(werr)) {
1280 goto done;
1283 b = pipe_cli->binding_handle;
1285 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1286 SAMR_ACCESS_ENUM_DOMAINS |
1287 SAMR_ACCESS_LOOKUP_DOMAIN,
1288 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1289 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1290 &connect_handle,
1291 &builtin_handle);
1292 if (!W_ERROR_IS_OK(werr)) {
1293 goto done;
1296 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1297 SAMR_ACCESS_ENUM_DOMAINS |
1298 SAMR_ACCESS_LOOKUP_DOMAIN,
1299 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1300 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1301 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1302 &connect_handle,
1303 &domain_handle,
1304 &domain_sid);
1305 if (!W_ERROR_IS_OK(werr)) {
1306 goto done;
1309 switch (r->in.filter) {
1310 case FILTER_NORMAL_ACCOUNT:
1311 filter = ACB_NORMAL;
1312 break;
1313 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1314 filter = ACB_TEMPDUP;
1315 break;
1316 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1317 filter = ACB_DOMTRUST;
1318 break;
1319 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1320 filter = ACB_WSTRUST;
1321 break;
1322 case FILTER_SERVER_TRUST_ACCOUNT:
1323 filter = ACB_SVRTRUST;
1324 break;
1325 default:
1326 break;
1329 status = dcerpc_samr_EnumDomainUsers(b,
1330 ctx,
1331 &domain_handle,
1332 r->in.resume_handle,
1333 filter,
1334 &sam,
1335 r->in.prefmaxlen,
1336 &entries_read,
1337 &result);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 werr = ntstatus_to_werror(status);
1340 goto done;
1342 werr = ntstatus_to_werror(result);
1343 if (NT_STATUS_IS_ERR(result)) {
1344 goto done;
1347 for (i=0; i < sam->count; i++) {
1349 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1350 domain_sid,
1351 &domain_handle,
1352 &builtin_handle,
1353 sam->entries[i].name.string,
1354 sam->entries[i].idx,
1355 r->in.level,
1356 r->out.buffer,
1357 r->out.entries_read);
1358 if (!NT_STATUS_IS_OK(status)) {
1359 werr = ntstatus_to_werror(status);
1360 goto done;
1364 done:
1365 /* if last query */
1366 if (NT_STATUS_IS_OK(result) ||
1367 NT_STATUS_IS_ERR(result)) {
1369 if (ctx->disable_policy_handle_cache) {
1370 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1371 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1372 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1376 return werr;
1379 /****************************************************************
1380 ****************************************************************/
1382 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1383 struct NetUserEnum *r)
1385 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1388 /****************************************************************
1389 ****************************************************************/
1391 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1392 struct samr_DispInfoGeneral *info,
1393 uint32_t *entries_read,
1394 void **buffer)
1396 struct NET_DISPLAY_USER *user = NULL;
1397 int i;
1399 user = talloc_zero_array(mem_ctx,
1400 struct NET_DISPLAY_USER,
1401 info->count);
1402 W_ERROR_HAVE_NO_MEMORY(user);
1404 for (i = 0; i < info->count; i++) {
1405 user[i].usri1_name = talloc_strdup(mem_ctx,
1406 info->entries[i].account_name.string);
1407 user[i].usri1_comment = talloc_strdup(mem_ctx,
1408 info->entries[i].description.string);
1409 user[i].usri1_flags =
1410 info->entries[i].acct_flags;
1411 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1412 info->entries[i].full_name.string);
1413 user[i].usri1_user_id =
1414 info->entries[i].rid;
1415 user[i].usri1_next_index =
1416 info->entries[i].idx;
1418 if (!user[i].usri1_name) {
1419 return WERR_NOT_ENOUGH_MEMORY;
1423 *buffer = talloc_memdup(mem_ctx, user,
1424 sizeof(struct NET_DISPLAY_USER) * info->count);
1425 W_ERROR_HAVE_NO_MEMORY(*buffer);
1427 *entries_read = info->count;
1429 return WERR_OK;
1432 /****************************************************************
1433 ****************************************************************/
1435 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1436 struct samr_DispInfoFull *info,
1437 uint32_t *entries_read,
1438 void **buffer)
1440 struct NET_DISPLAY_MACHINE *machine = NULL;
1441 int i;
1443 machine = talloc_zero_array(mem_ctx,
1444 struct NET_DISPLAY_MACHINE,
1445 info->count);
1446 W_ERROR_HAVE_NO_MEMORY(machine);
1448 for (i = 0; i < info->count; i++) {
1449 machine[i].usri2_name = talloc_strdup(mem_ctx,
1450 info->entries[i].account_name.string);
1451 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1452 info->entries[i].description.string);
1453 machine[i].usri2_flags =
1454 info->entries[i].acct_flags;
1455 machine[i].usri2_user_id =
1456 info->entries[i].rid;
1457 machine[i].usri2_next_index =
1458 info->entries[i].idx;
1460 if (!machine[i].usri2_name) {
1461 return WERR_NOT_ENOUGH_MEMORY;
1465 *buffer = talloc_memdup(mem_ctx, machine,
1466 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1467 W_ERROR_HAVE_NO_MEMORY(*buffer);
1469 *entries_read = info->count;
1471 return WERR_OK;
1474 /****************************************************************
1475 ****************************************************************/
1477 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1478 struct samr_DispInfoFullGroups *info,
1479 uint32_t *entries_read,
1480 void **buffer)
1482 struct NET_DISPLAY_GROUP *group = NULL;
1483 int i;
1485 group = talloc_zero_array(mem_ctx,
1486 struct NET_DISPLAY_GROUP,
1487 info->count);
1488 W_ERROR_HAVE_NO_MEMORY(group);
1490 for (i = 0; i < info->count; i++) {
1491 group[i].grpi3_name = talloc_strdup(mem_ctx,
1492 info->entries[i].account_name.string);
1493 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1494 info->entries[i].description.string);
1495 group[i].grpi3_group_id =
1496 info->entries[i].rid;
1497 group[i].grpi3_attributes =
1498 info->entries[i].acct_flags;
1499 group[i].grpi3_next_index =
1500 info->entries[i].idx;
1502 if (!group[i].grpi3_name) {
1503 return WERR_NOT_ENOUGH_MEMORY;
1507 *buffer = talloc_memdup(mem_ctx, group,
1508 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1509 W_ERROR_HAVE_NO_MEMORY(*buffer);
1511 *entries_read = info->count;
1513 return WERR_OK;
1517 /****************************************************************
1518 ****************************************************************/
1520 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1521 union samr_DispInfo *info,
1522 uint32_t level,
1523 uint32_t *entries_read,
1524 void **buffer)
1526 switch (level) {
1527 case 1:
1528 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1529 &info->info1,
1530 entries_read,
1531 buffer);
1532 case 2:
1533 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1534 &info->info2,
1535 entries_read,
1536 buffer);
1537 case 3:
1538 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1539 &info->info3,
1540 entries_read,
1541 buffer);
1542 default:
1543 break;
1546 return WERR_INVALID_LEVEL;
1549 /****************************************************************
1550 ****************************************************************/
1552 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1553 struct NetQueryDisplayInformation *r)
1555 struct rpc_pipe_client *pipe_cli = NULL;
1556 struct policy_handle connect_handle;
1557 struct dom_sid2 *domain_sid = NULL;
1558 struct policy_handle domain_handle;
1559 union samr_DispInfo info;
1560 struct dcerpc_binding_handle *b = NULL;
1562 uint32_t total_size = 0;
1563 uint32_t returned_size = 0;
1565 NTSTATUS status;
1566 NTSTATUS result = NT_STATUS_OK;
1567 WERROR werr;
1568 WERROR werr_tmp;
1570 *r->out.entries_read = 0;
1572 ZERO_STRUCT(connect_handle);
1573 ZERO_STRUCT(domain_handle);
1575 switch (r->in.level) {
1576 case 1:
1577 case 2:
1578 case 3:
1579 break;
1580 default:
1581 return WERR_INVALID_LEVEL;
1584 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1585 &ndr_table_samr,
1586 &pipe_cli);
1587 if (!W_ERROR_IS_OK(werr)) {
1588 goto done;
1591 b = pipe_cli->binding_handle;
1593 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1594 SAMR_ACCESS_ENUM_DOMAINS |
1595 SAMR_ACCESS_LOOKUP_DOMAIN,
1596 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1597 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1598 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1599 &connect_handle,
1600 &domain_handle,
1601 &domain_sid);
1602 if (!W_ERROR_IS_OK(werr)) {
1603 goto done;
1606 status = dcerpc_samr_QueryDisplayInfo2(b,
1607 ctx,
1608 &domain_handle,
1609 r->in.level,
1610 r->in.idx,
1611 r->in.entries_requested,
1612 r->in.prefmaxlen,
1613 &total_size,
1614 &returned_size,
1615 &info,
1616 &result);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 werr = ntstatus_to_werror(status);
1619 goto done;
1621 werr = ntstatus_to_werror(result);
1622 if (NT_STATUS_IS_ERR(result)) {
1623 goto done;
1626 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1627 r->in.level,
1628 r->out.entries_read,
1629 r->out.buffer);
1630 if (!W_ERROR_IS_OK(werr_tmp)) {
1631 werr = werr_tmp;
1633 done:
1634 /* if last query */
1635 if (NT_STATUS_IS_OK(result) ||
1636 NT_STATUS_IS_ERR(result)) {
1638 if (ctx->disable_policy_handle_cache) {
1639 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1640 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1644 return werr;
1648 /****************************************************************
1649 ****************************************************************/
1652 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1653 struct NetQueryDisplayInformation *r)
1655 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1658 /****************************************************************
1659 ****************************************************************/
1661 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1662 struct NetUserChangePassword *r)
1664 return WERR_NOT_SUPPORTED;
1667 /****************************************************************
1668 ****************************************************************/
1670 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1671 struct NetUserChangePassword *r)
1673 return WERR_NOT_SUPPORTED;
1676 /****************************************************************
1677 ****************************************************************/
1679 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1680 struct NetUserGetInfo *r)
1682 struct rpc_pipe_client *pipe_cli = NULL;
1683 NTSTATUS status, result;
1684 WERROR werr;
1686 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1687 struct lsa_String lsa_account_name;
1688 struct dom_sid2 *domain_sid = NULL;
1689 struct samr_Ids user_rids, name_types;
1690 uint32_t num_entries = 0;
1691 struct dcerpc_binding_handle *b = NULL;
1693 ZERO_STRUCT(connect_handle);
1694 ZERO_STRUCT(domain_handle);
1695 ZERO_STRUCT(builtin_handle);
1696 ZERO_STRUCT(user_handle);
1698 if (!r->out.buffer) {
1699 return WERR_INVALID_PARAMETER;
1702 switch (r->in.level) {
1703 case 0:
1704 case 1:
1705 case 2:
1706 case 3:
1707 case 4:
1708 case 10:
1709 case 11:
1710 case 20:
1711 case 23:
1712 break;
1713 default:
1714 werr = WERR_INVALID_LEVEL;
1715 goto done;
1718 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1719 &ndr_table_samr,
1720 &pipe_cli);
1721 if (!W_ERROR_IS_OK(werr)) {
1722 goto done;
1725 b = pipe_cli->binding_handle;
1727 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1728 SAMR_ACCESS_ENUM_DOMAINS |
1729 SAMR_ACCESS_LOOKUP_DOMAIN,
1730 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1731 &connect_handle,
1732 &domain_handle,
1733 &domain_sid);
1734 if (!W_ERROR_IS_OK(werr)) {
1735 goto done;
1738 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1739 SAMR_ACCESS_ENUM_DOMAINS |
1740 SAMR_ACCESS_LOOKUP_DOMAIN,
1741 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1742 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1743 &connect_handle,
1744 &builtin_handle);
1745 if (!W_ERROR_IS_OK(werr)) {
1746 goto done;
1749 init_lsa_String(&lsa_account_name, r->in.user_name);
1751 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1752 &domain_handle,
1754 &lsa_account_name,
1755 &user_rids,
1756 &name_types,
1757 &result);
1758 if (any_nt_status_not_ok(status, result, &status)) {
1759 werr = ntstatus_to_werror(status);
1760 goto done;
1762 if (user_rids.count != 1) {
1763 werr = WERR_BAD_NET_RESP;
1764 goto done;
1766 if (name_types.count != 1) {
1767 werr = WERR_BAD_NET_RESP;
1768 goto done;
1771 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1772 domain_sid,
1773 &domain_handle,
1774 &builtin_handle,
1775 r->in.user_name,
1776 user_rids.ids[0],
1777 r->in.level,
1778 r->out.buffer,
1779 &num_entries);
1780 if (!NT_STATUS_IS_OK(status)) {
1781 werr = ntstatus_to_werror(status);
1782 goto done;
1785 done:
1786 if (is_valid_policy_hnd(&user_handle) && b) {
1787 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1790 if (ctx->disable_policy_handle_cache) {
1791 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1792 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1795 return werr;
1798 /****************************************************************
1799 ****************************************************************/
1801 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1802 struct NetUserGetInfo *r)
1804 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1807 /****************************************************************
1808 ****************************************************************/
1810 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1811 struct NetUserSetInfo *r)
1813 struct rpc_pipe_client *pipe_cli = NULL;
1814 NTSTATUS status, result;
1815 WERROR werr;
1817 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1818 struct lsa_String lsa_account_name;
1819 struct dom_sid2 *domain_sid = NULL;
1820 struct samr_Ids user_rids, name_types;
1821 uint32_t user_mask = 0;
1823 struct USER_INFO_X uX;
1824 struct dcerpc_binding_handle *b = NULL;
1825 DATA_BLOB session_key;
1827 ZERO_STRUCT(connect_handle);
1828 ZERO_STRUCT(domain_handle);
1829 ZERO_STRUCT(builtin_handle);
1830 ZERO_STRUCT(user_handle);
1832 if (!r->in.buffer) {
1833 return WERR_INVALID_PARAMETER;
1836 switch (r->in.level) {
1837 case 0:
1838 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1839 break;
1840 case 1003:
1841 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1842 break;
1843 case 1006:
1844 case 1007:
1845 case 1009:
1846 case 1011:
1847 case 1014:
1848 case 1052:
1849 case 1053:
1850 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1851 break;
1852 case 1012:
1853 case 1024:
1854 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1855 break;
1856 case 1051:
1857 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1858 SAMR_USER_ACCESS_GET_GROUPS;
1859 break;
1860 case 3:
1861 user_mask = SEC_STD_READ_CONTROL |
1862 SEC_STD_WRITE_DAC |
1863 SAMR_USER_ACCESS_GET_GROUPS |
1864 SAMR_USER_ACCESS_SET_PASSWORD |
1865 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1866 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1867 SAMR_USER_ACCESS_SET_LOC_COM;
1868 break;
1869 case 1:
1870 case 2:
1871 case 4:
1872 case 21:
1873 case 22:
1874 case 1005:
1875 case 1008:
1876 case 1010:
1877 case 1017:
1878 case 1020:
1879 werr = WERR_NOT_SUPPORTED;
1880 goto done;
1881 default:
1882 werr = WERR_INVALID_LEVEL;
1883 goto done;
1886 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1887 &ndr_table_samr,
1888 &pipe_cli);
1889 if (!W_ERROR_IS_OK(werr)) {
1890 goto done;
1893 b = pipe_cli->binding_handle;
1895 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1896 SAMR_ACCESS_ENUM_DOMAINS |
1897 SAMR_ACCESS_LOOKUP_DOMAIN,
1898 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1899 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1900 &connect_handle,
1901 &domain_handle,
1902 &domain_sid);
1903 if (!W_ERROR_IS_OK(werr)) {
1904 goto done;
1907 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1908 SAMR_ACCESS_ENUM_DOMAINS |
1909 SAMR_ACCESS_LOOKUP_DOMAIN,
1910 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1911 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1912 &connect_handle,
1913 &builtin_handle);
1914 if (!W_ERROR_IS_OK(werr)) {
1915 goto done;
1918 init_lsa_String(&lsa_account_name, r->in.user_name);
1920 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1921 &domain_handle,
1923 &lsa_account_name,
1924 &user_rids,
1925 &name_types,
1926 &result);
1927 if (any_nt_status_not_ok(status, result, &status)) {
1928 werr = ntstatus_to_werror(status);
1929 goto done;
1931 if (user_rids.count != 1) {
1932 werr = WERR_BAD_NET_RESP;
1933 goto done;
1935 if (name_types.count != 1) {
1936 werr = WERR_BAD_NET_RESP;
1937 goto done;
1940 status = dcerpc_samr_OpenUser(b, talloc_tos(),
1941 &domain_handle,
1942 user_mask,
1943 user_rids.ids[0],
1944 &user_handle,
1945 &result);
1946 if (any_nt_status_not_ok(status, result, &status)) {
1947 werr = ntstatus_to_werror(status);
1948 goto done;
1951 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1952 if (!NT_STATUS_IS_OK(status)) {
1953 werr = ntstatus_to_werror(status);
1954 goto done;
1957 status = dcerpc_binding_handle_transport_session_key(
1958 b, talloc_tos(), &session_key);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 werr = ntstatus_to_werror(status);
1961 goto done;
1964 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1965 &session_key,
1966 &user_handle,
1967 &uX);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 werr = ntstatus_to_werror(status);
1970 goto done;
1973 werr = WERR_OK;
1975 done:
1976 if (is_valid_policy_hnd(&user_handle) && b) {
1977 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1980 if (ctx->disable_policy_handle_cache) {
1981 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1982 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1983 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1986 return werr;
1989 /****************************************************************
1990 ****************************************************************/
1992 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1993 struct NetUserSetInfo *r)
1995 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1998 /****************************************************************
1999 ****************************************************************/
2001 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2002 struct rpc_pipe_client *pipe_cli,
2003 struct policy_handle *domain_handle,
2004 struct samr_DomInfo1 *info1,
2005 struct samr_DomInfo3 *info3,
2006 struct samr_DomInfo5 *info5,
2007 struct samr_DomInfo6 *info6,
2008 struct samr_DomInfo7 *info7,
2009 struct samr_DomInfo12 *info12)
2011 NTSTATUS status, result;
2012 union samr_DomainInfo *dom_info = NULL;
2013 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2015 if (info1) {
2016 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2017 domain_handle,
2019 &dom_info,
2020 &result);
2021 NT_STATUS_NOT_OK_RETURN(status);
2022 NT_STATUS_NOT_OK_RETURN(result);
2024 *info1 = dom_info->info1;
2027 if (info3) {
2028 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2029 domain_handle,
2031 &dom_info,
2032 &result);
2033 NT_STATUS_NOT_OK_RETURN(status);
2034 NT_STATUS_NOT_OK_RETURN(result);
2036 *info3 = dom_info->info3;
2039 if (info5) {
2040 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2041 domain_handle,
2043 &dom_info,
2044 &result);
2045 NT_STATUS_NOT_OK_RETURN(status);
2046 NT_STATUS_NOT_OK_RETURN(result);
2048 *info5 = dom_info->info5;
2051 if (info6) {
2052 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2053 domain_handle,
2055 &dom_info,
2056 &result);
2057 NT_STATUS_NOT_OK_RETURN(status);
2058 NT_STATUS_NOT_OK_RETURN(result);
2060 *info6 = dom_info->info6;
2063 if (info7) {
2064 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2065 domain_handle,
2067 &dom_info,
2068 &result);
2069 NT_STATUS_NOT_OK_RETURN(status);
2070 NT_STATUS_NOT_OK_RETURN(result);
2072 *info7 = dom_info->info7;
2075 if (info12) {
2076 status = dcerpc_samr_QueryDomainInfo2(b, mem_ctx,
2077 domain_handle,
2079 &dom_info,
2080 &result);
2081 NT_STATUS_NOT_OK_RETURN(status);
2082 NT_STATUS_NOT_OK_RETURN(result);
2084 *info12 = dom_info->info12;
2087 return NT_STATUS_OK;
2090 /****************************************************************
2091 ****************************************************************/
2093 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
2094 struct rpc_pipe_client *pipe_cli,
2095 struct policy_handle *domain_handle,
2096 struct USER_MODALS_INFO_0 *info0)
2098 NTSTATUS status;
2099 struct samr_DomInfo1 dom_info1;
2100 struct samr_DomInfo3 dom_info3;
2102 ZERO_STRUCTP(info0);
2104 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2105 pipe_cli,
2106 domain_handle,
2107 &dom_info1,
2108 &dom_info3,
2109 NULL,
2110 NULL,
2111 NULL,
2112 NULL);
2113 NT_STATUS_NOT_OK_RETURN(status);
2115 info0->usrmod0_min_passwd_len =
2116 dom_info1.min_password_length;
2117 info0->usrmod0_max_passwd_age =
2118 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2119 info0->usrmod0_min_passwd_age =
2120 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2121 info0->usrmod0_password_hist_len =
2122 dom_info1.password_history_length;
2124 info0->usrmod0_force_logoff =
2125 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2127 return NT_STATUS_OK;
2130 /****************************************************************
2131 ****************************************************************/
2133 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2134 struct rpc_pipe_client *pipe_cli,
2135 struct policy_handle *domain_handle,
2136 struct USER_MODALS_INFO_1 *info1)
2138 NTSTATUS status;
2139 struct samr_DomInfo6 dom_info6;
2140 struct samr_DomInfo7 dom_info7;
2142 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2143 pipe_cli,
2144 domain_handle,
2145 NULL,
2146 NULL,
2147 NULL,
2148 &dom_info6,
2149 &dom_info7,
2150 NULL);
2151 NT_STATUS_NOT_OK_RETURN(status);
2153 info1->usrmod1_primary =
2154 talloc_strdup(mem_ctx, dom_info6.primary.string);
2156 info1->usrmod1_role = dom_info7.role;
2158 return NT_STATUS_OK;
2161 /****************************************************************
2162 ****************************************************************/
2164 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2165 struct rpc_pipe_client *pipe_cli,
2166 struct policy_handle *domain_handle,
2167 struct dom_sid *domain_sid,
2168 struct USER_MODALS_INFO_2 *info2)
2170 NTSTATUS status;
2171 struct samr_DomInfo5 dom_info5;
2173 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2174 pipe_cli,
2175 domain_handle,
2176 NULL,
2177 NULL,
2178 &dom_info5,
2179 NULL,
2180 NULL,
2181 NULL);
2182 NT_STATUS_NOT_OK_RETURN(status);
2184 info2->usrmod2_domain_name =
2185 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2186 info2->usrmod2_domain_id =
2187 (struct domsid *)dom_sid_dup(mem_ctx, domain_sid);
2189 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2190 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2192 return NT_STATUS_OK;
2195 /****************************************************************
2196 ****************************************************************/
2198 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2199 struct rpc_pipe_client *pipe_cli,
2200 struct policy_handle *domain_handle,
2201 struct USER_MODALS_INFO_3 *info3)
2203 NTSTATUS status;
2204 struct samr_DomInfo12 dom_info12;
2206 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2207 pipe_cli,
2208 domain_handle,
2209 NULL,
2210 NULL,
2211 NULL,
2212 NULL,
2213 NULL,
2214 &dom_info12);
2215 NT_STATUS_NOT_OK_RETURN(status);
2217 info3->usrmod3_lockout_duration =
2218 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2219 info3->usrmod3_lockout_observation_window =
2220 nt_time_to_unix_abs(&dom_info12.lockout_window);
2221 info3->usrmod3_lockout_threshold =
2222 dom_info12.lockout_threshold;
2224 return NT_STATUS_OK;
2227 /****************************************************************
2228 ****************************************************************/
2230 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2231 struct rpc_pipe_client *pipe_cli,
2232 uint32_t level,
2233 struct policy_handle *domain_handle,
2234 struct dom_sid *domain_sid,
2235 uint8_t **buffer)
2237 NTSTATUS status;
2239 struct USER_MODALS_INFO_0 info0;
2240 struct USER_MODALS_INFO_1 info1;
2241 struct USER_MODALS_INFO_2 info2;
2242 struct USER_MODALS_INFO_3 info3;
2244 if (!buffer) {
2245 return ERROR_INSUFFICIENT_BUFFER;
2248 switch (level) {
2249 case 0:
2250 status = query_USER_MODALS_INFO_0(mem_ctx,
2251 pipe_cli,
2252 domain_handle,
2253 &info0);
2254 NT_STATUS_NOT_OK_RETURN(status);
2256 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2257 sizeof(info0));
2258 break;
2260 case 1:
2261 status = query_USER_MODALS_INFO_1(mem_ctx,
2262 pipe_cli,
2263 domain_handle,
2264 &info1);
2265 NT_STATUS_NOT_OK_RETURN(status);
2267 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2268 sizeof(info1));
2269 break;
2270 case 2:
2271 status = query_USER_MODALS_INFO_2(mem_ctx,
2272 pipe_cli,
2273 domain_handle,
2274 domain_sid,
2275 &info2);
2276 NT_STATUS_NOT_OK_RETURN(status);
2278 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2279 sizeof(info2));
2280 break;
2281 case 3:
2282 status = query_USER_MODALS_INFO_3(mem_ctx,
2283 pipe_cli,
2284 domain_handle,
2285 &info3);
2286 NT_STATUS_NOT_OK_RETURN(status);
2288 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2289 sizeof(info3));
2290 break;
2291 default:
2292 break;
2295 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2297 return NT_STATUS_OK;
2300 /****************************************************************
2301 ****************************************************************/
2303 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2304 struct NetUserModalsGet *r)
2306 struct rpc_pipe_client *pipe_cli = NULL;
2307 NTSTATUS status;
2308 WERROR werr;
2310 struct policy_handle connect_handle, domain_handle;
2311 struct dom_sid2 *domain_sid = NULL;
2312 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2314 ZERO_STRUCT(connect_handle);
2315 ZERO_STRUCT(domain_handle);
2317 if (!r->out.buffer) {
2318 return WERR_INVALID_PARAMETER;
2321 switch (r->in.level) {
2322 case 0:
2323 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2324 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2325 break;
2326 case 1:
2327 case 2:
2328 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2329 break;
2330 case 3:
2331 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2332 break;
2333 default:
2334 werr = WERR_INVALID_LEVEL;
2335 goto done;
2338 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2339 &ndr_table_samr,
2340 &pipe_cli);
2341 if (!W_ERROR_IS_OK(werr)) {
2342 goto done;
2345 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2346 SAMR_ACCESS_ENUM_DOMAINS |
2347 SAMR_ACCESS_LOOKUP_DOMAIN,
2348 access_mask,
2349 &connect_handle,
2350 &domain_handle,
2351 &domain_sid);
2352 if (!W_ERROR_IS_OK(werr)) {
2353 goto done;
2356 /* 0: 1 + 3 */
2357 /* 1: 6 + 7 */
2358 /* 2: 5 */
2359 /* 3: 12 (DomainInfo2) */
2361 status = query_USER_MODALS_INFO_to_buffer(ctx,
2362 pipe_cli,
2363 r->in.level,
2364 &domain_handle,
2365 domain_sid,
2366 r->out.buffer);
2367 if (!NT_STATUS_IS_OK(status)) {
2368 werr = ntstatus_to_werror(status);
2369 goto done;
2372 done:
2373 if (ctx->disable_policy_handle_cache) {
2374 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2375 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2378 return werr;
2381 /****************************************************************
2382 ****************************************************************/
2384 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2385 struct NetUserModalsGet *r)
2387 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2390 /****************************************************************
2391 ****************************************************************/
2393 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2394 struct rpc_pipe_client *pipe_cli,
2395 struct policy_handle *domain_handle,
2396 struct samr_DomInfo1 *info1,
2397 struct samr_DomInfo3 *info3,
2398 struct samr_DomInfo12 *info12)
2400 NTSTATUS status, result;
2401 union samr_DomainInfo dom_info;
2402 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2404 if (info1) {
2406 ZERO_STRUCT(dom_info);
2408 dom_info.info1 = *info1;
2410 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2411 domain_handle,
2413 &dom_info,
2414 &result);
2415 NT_STATUS_NOT_OK_RETURN(status);
2416 NT_STATUS_NOT_OK_RETURN(result);
2419 if (info3) {
2421 ZERO_STRUCT(dom_info);
2423 dom_info.info3 = *info3;
2425 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2426 domain_handle,
2428 &dom_info,
2429 &result);
2431 NT_STATUS_NOT_OK_RETURN(status);
2432 NT_STATUS_NOT_OK_RETURN(result);
2435 if (info12) {
2437 ZERO_STRUCT(dom_info);
2439 dom_info.info12 = *info12;
2441 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2442 domain_handle,
2444 &dom_info,
2445 &result);
2447 NT_STATUS_NOT_OK_RETURN(status);
2448 NT_STATUS_NOT_OK_RETURN(result);
2451 return NT_STATUS_OK;
2454 /****************************************************************
2455 ****************************************************************/
2457 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2458 struct rpc_pipe_client *pipe_cli,
2459 struct policy_handle *domain_handle,
2460 struct USER_MODALS_INFO_0 *info0)
2462 NTSTATUS status;
2463 struct samr_DomInfo1 dom_info_1;
2464 struct samr_DomInfo3 dom_info_3;
2466 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2467 pipe_cli,
2468 domain_handle,
2469 &dom_info_1,
2470 &dom_info_3,
2471 NULL,
2472 NULL,
2473 NULL,
2474 NULL);
2475 NT_STATUS_NOT_OK_RETURN(status);
2477 dom_info_1.min_password_length =
2478 info0->usrmod0_min_passwd_len;
2479 dom_info_1.password_history_length =
2480 info0->usrmod0_password_hist_len;
2482 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2483 info0->usrmod0_max_passwd_age);
2484 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2485 info0->usrmod0_min_passwd_age);
2487 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2488 info0->usrmod0_force_logoff);
2490 return set_USER_MODALS_INFO_rpc(mem_ctx,
2491 pipe_cli,
2492 domain_handle,
2493 &dom_info_1,
2494 &dom_info_3,
2495 NULL);
2498 /****************************************************************
2499 ****************************************************************/
2501 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2502 struct rpc_pipe_client *pipe_cli,
2503 struct policy_handle *domain_handle,
2504 struct USER_MODALS_INFO_3 *info3)
2506 NTSTATUS status;
2507 struct samr_DomInfo12 dom_info_12;
2509 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2510 pipe_cli,
2511 domain_handle,
2512 NULL,
2513 NULL,
2514 NULL,
2515 NULL,
2516 NULL,
2517 &dom_info_12);
2518 NT_STATUS_NOT_OK_RETURN(status);
2520 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2521 info3->usrmod3_lockout_duration);
2522 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2523 info3->usrmod3_lockout_observation_window);
2524 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2526 return set_USER_MODALS_INFO_rpc(mem_ctx,
2527 pipe_cli,
2528 domain_handle,
2529 NULL,
2530 NULL,
2531 &dom_info_12);
2534 /****************************************************************
2535 ****************************************************************/
2537 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2538 struct rpc_pipe_client *pipe_cli,
2539 struct policy_handle *domain_handle,
2540 struct USER_MODALS_INFO_1001 *info1001)
2542 NTSTATUS status;
2543 struct samr_DomInfo1 dom_info_1;
2545 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2546 pipe_cli,
2547 domain_handle,
2548 &dom_info_1,
2549 NULL,
2550 NULL,
2551 NULL,
2552 NULL,
2553 NULL);
2554 NT_STATUS_NOT_OK_RETURN(status);
2556 dom_info_1.min_password_length =
2557 info1001->usrmod1001_min_passwd_len;
2559 return set_USER_MODALS_INFO_rpc(mem_ctx,
2560 pipe_cli,
2561 domain_handle,
2562 &dom_info_1,
2563 NULL,
2564 NULL);
2567 /****************************************************************
2568 ****************************************************************/
2570 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2571 struct rpc_pipe_client *pipe_cli,
2572 struct policy_handle *domain_handle,
2573 struct USER_MODALS_INFO_1002 *info1002)
2575 NTSTATUS status;
2576 struct samr_DomInfo1 dom_info_1;
2578 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2579 pipe_cli,
2580 domain_handle,
2581 &dom_info_1,
2582 NULL,
2583 NULL,
2584 NULL,
2585 NULL,
2586 NULL);
2587 NT_STATUS_NOT_OK_RETURN(status);
2589 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2590 info1002->usrmod1002_max_passwd_age);
2592 return set_USER_MODALS_INFO_rpc(mem_ctx,
2593 pipe_cli,
2594 domain_handle,
2595 &dom_info_1,
2596 NULL,
2597 NULL);
2600 /****************************************************************
2601 ****************************************************************/
2603 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2604 struct rpc_pipe_client *pipe_cli,
2605 struct policy_handle *domain_handle,
2606 struct USER_MODALS_INFO_1003 *info1003)
2608 NTSTATUS status;
2609 struct samr_DomInfo1 dom_info_1;
2611 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2612 pipe_cli,
2613 domain_handle,
2614 &dom_info_1,
2615 NULL,
2616 NULL,
2617 NULL,
2618 NULL,
2619 NULL);
2620 NT_STATUS_NOT_OK_RETURN(status);
2622 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2623 info1003->usrmod1003_min_passwd_age);
2625 return set_USER_MODALS_INFO_rpc(mem_ctx,
2626 pipe_cli,
2627 domain_handle,
2628 &dom_info_1,
2629 NULL,
2630 NULL);
2633 /****************************************************************
2634 ****************************************************************/
2636 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2637 struct rpc_pipe_client *pipe_cli,
2638 struct policy_handle *domain_handle,
2639 struct USER_MODALS_INFO_1004 *info1004)
2641 NTSTATUS status;
2642 struct samr_DomInfo3 dom_info_3;
2644 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2645 pipe_cli,
2646 domain_handle,
2647 NULL,
2648 &dom_info_3,
2649 NULL,
2650 NULL,
2651 NULL,
2652 NULL);
2653 NT_STATUS_NOT_OK_RETURN(status);
2655 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2656 info1004->usrmod1004_force_logoff);
2658 return set_USER_MODALS_INFO_rpc(mem_ctx,
2659 pipe_cli,
2660 domain_handle,
2661 NULL,
2662 &dom_info_3,
2663 NULL);
2666 /****************************************************************
2667 ****************************************************************/
2669 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2670 struct rpc_pipe_client *pipe_cli,
2671 struct policy_handle *domain_handle,
2672 struct USER_MODALS_INFO_1005 *info1005)
2674 NTSTATUS status;
2675 struct samr_DomInfo1 dom_info_1;
2677 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2678 pipe_cli,
2679 domain_handle,
2680 &dom_info_1,
2681 NULL,
2682 NULL,
2683 NULL,
2684 NULL,
2685 NULL);
2686 NT_STATUS_NOT_OK_RETURN(status);
2688 dom_info_1.password_history_length =
2689 info1005->usrmod1005_password_hist_len;
2691 return set_USER_MODALS_INFO_rpc(mem_ctx,
2692 pipe_cli,
2693 domain_handle,
2694 &dom_info_1,
2695 NULL,
2696 NULL);
2699 /****************************************************************
2700 ****************************************************************/
2702 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2703 struct rpc_pipe_client *pipe_cli,
2704 uint32_t level,
2705 struct policy_handle *domain_handle,
2706 struct dom_sid *domain_sid,
2707 uint8_t *buffer)
2709 struct USER_MODALS_INFO_0 *info0;
2710 struct USER_MODALS_INFO_3 *info3;
2711 struct USER_MODALS_INFO_1001 *info1001;
2712 struct USER_MODALS_INFO_1002 *info1002;
2713 struct USER_MODALS_INFO_1003 *info1003;
2714 struct USER_MODALS_INFO_1004 *info1004;
2715 struct USER_MODALS_INFO_1005 *info1005;
2717 if (!buffer) {
2718 return ERROR_INSUFFICIENT_BUFFER;
2721 switch (level) {
2722 case 0:
2723 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2724 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2725 pipe_cli,
2726 domain_handle,
2727 info0);
2728 case 3:
2729 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2730 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2731 pipe_cli,
2732 domain_handle,
2733 info3);
2734 case 1001:
2735 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2736 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2737 pipe_cli,
2738 domain_handle,
2739 info1001);
2740 case 1002:
2741 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2742 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2743 pipe_cli,
2744 domain_handle,
2745 info1002);
2746 case 1003:
2747 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2748 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2749 pipe_cli,
2750 domain_handle,
2751 info1003);
2752 case 1004:
2753 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2754 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2755 pipe_cli,
2756 domain_handle,
2757 info1004);
2758 case 1005:
2759 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2760 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2761 pipe_cli,
2762 domain_handle,
2763 info1005);
2765 default:
2766 break;
2769 return NT_STATUS_OK;
2772 /****************************************************************
2773 ****************************************************************/
2775 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2776 struct NetUserModalsSet *r)
2778 struct rpc_pipe_client *pipe_cli = NULL;
2779 NTSTATUS status;
2780 WERROR werr;
2782 struct policy_handle connect_handle, domain_handle;
2783 struct dom_sid2 *domain_sid = NULL;
2784 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2786 ZERO_STRUCT(connect_handle);
2787 ZERO_STRUCT(domain_handle);
2789 if (!r->in.buffer) {
2790 return WERR_INVALID_PARAMETER;
2793 switch (r->in.level) {
2794 case 0:
2795 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2796 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2797 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2798 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2799 break;
2800 case 3:
2801 case 1001:
2802 case 1002:
2803 case 1003:
2804 case 1005:
2805 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2806 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2807 break;
2808 case 1004:
2809 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2810 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2811 break;
2812 case 1:
2813 case 2:
2814 case 1006:
2815 case 1007:
2816 werr = WERR_NOT_SUPPORTED;
2817 break;
2818 default:
2819 werr = WERR_INVALID_LEVEL;
2820 goto done;
2823 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2824 &ndr_table_samr,
2825 &pipe_cli);
2826 if (!W_ERROR_IS_OK(werr)) {
2827 goto done;
2830 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2831 SAMR_ACCESS_ENUM_DOMAINS |
2832 SAMR_ACCESS_LOOKUP_DOMAIN,
2833 access_mask,
2834 &connect_handle,
2835 &domain_handle,
2836 &domain_sid);
2837 if (!W_ERROR_IS_OK(werr)) {
2838 goto done;
2841 status = set_USER_MODALS_INFO_buffer(ctx,
2842 pipe_cli,
2843 r->in.level,
2844 &domain_handle,
2845 domain_sid,
2846 r->in.buffer);
2847 if (!NT_STATUS_IS_OK(status)) {
2848 werr = ntstatus_to_werror(status);
2849 goto done;
2852 done:
2853 if (ctx->disable_policy_handle_cache) {
2854 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2855 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2858 return werr;
2861 /****************************************************************
2862 ****************************************************************/
2864 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2865 struct NetUserModalsSet *r)
2867 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2870 /****************************************************************
2871 ****************************************************************/
2873 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2874 uint32_t level,
2875 const char *group_name,
2876 uint32_t attributes,
2877 uint8_t **buffer,
2878 uint32_t *num_entries)
2880 struct GROUP_USERS_INFO_0 u0;
2881 struct GROUP_USERS_INFO_1 u1;
2883 switch (level) {
2884 case 0:
2885 if (group_name) {
2886 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2887 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2888 } else {
2889 u0.grui0_name = NULL;
2892 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2893 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2894 break;
2895 case 1:
2896 if (group_name) {
2897 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2898 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2899 } else {
2900 u1.grui1_name = NULL;
2903 u1.grui1_attributes = attributes;
2905 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2906 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2907 break;
2908 default:
2909 return NT_STATUS_INVALID_INFO_CLASS;
2912 return NT_STATUS_OK;
2915 /****************************************************************
2916 ****************************************************************/
2918 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2919 struct NetUserGetGroups *r)
2921 struct rpc_pipe_client *pipe_cli = NULL;
2922 struct policy_handle connect_handle, domain_handle, user_handle;
2923 struct lsa_String lsa_account_name;
2924 struct dom_sid2 *domain_sid = NULL;
2925 struct samr_Ids user_rids, name_types;
2926 struct samr_RidWithAttributeArray *rid_array = NULL;
2927 struct lsa_Strings names;
2928 struct samr_Ids types;
2929 uint32_t *rids = NULL;
2931 int i;
2932 uint32_t entries_read = 0;
2934 NTSTATUS status;
2935 NTSTATUS result = NT_STATUS_OK;
2936 WERROR werr;
2937 struct dcerpc_binding_handle *b = NULL;
2939 ZERO_STRUCT(connect_handle);
2940 ZERO_STRUCT(domain_handle);
2942 if (!r->out.buffer) {
2943 return WERR_INVALID_PARAMETER;
2946 *r->out.buffer = NULL;
2947 *r->out.entries_read = 0;
2948 *r->out.total_entries = 0;
2950 switch (r->in.level) {
2951 case 0:
2952 case 1:
2953 break;
2954 default:
2955 return WERR_INVALID_LEVEL;
2958 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2959 &ndr_table_samr,
2960 &pipe_cli);
2961 if (!W_ERROR_IS_OK(werr)) {
2962 goto done;
2965 b = pipe_cli->binding_handle;
2967 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2968 SAMR_ACCESS_ENUM_DOMAINS |
2969 SAMR_ACCESS_LOOKUP_DOMAIN,
2970 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2971 &connect_handle,
2972 &domain_handle,
2973 &domain_sid);
2974 if (!W_ERROR_IS_OK(werr)) {
2975 goto done;
2978 init_lsa_String(&lsa_account_name, r->in.user_name);
2980 status = dcerpc_samr_LookupNames(b, talloc_tos(),
2981 &domain_handle,
2983 &lsa_account_name,
2984 &user_rids,
2985 &name_types,
2986 &result);
2987 if (any_nt_status_not_ok(status, result, &status)) {
2988 werr = ntstatus_to_werror(status);
2989 goto done;
2991 if (user_rids.count != 1) {
2992 werr = WERR_BAD_NET_RESP;
2993 goto done;
2995 if (name_types.count != 1) {
2996 werr = WERR_BAD_NET_RESP;
2997 goto done;
3000 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3001 &domain_handle,
3002 SAMR_USER_ACCESS_GET_GROUPS,
3003 user_rids.ids[0],
3004 &user_handle,
3005 &result);
3006 if (any_nt_status_not_ok(status, result, &status)) {
3007 werr = ntstatus_to_werror(status);
3008 goto done;
3011 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3012 &user_handle,
3013 &rid_array,
3014 &result);
3015 if (any_nt_status_not_ok(status, result, &status)) {
3016 werr = ntstatus_to_werror(status);
3017 goto done;
3020 rids = talloc_array(ctx, uint32_t, rid_array->count);
3021 if (!rids) {
3022 werr = WERR_NOT_ENOUGH_MEMORY;
3023 goto done;
3026 for (i=0; i < rid_array->count; i++) {
3027 rids[i] = rid_array->rids[i].rid;
3030 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3031 &domain_handle,
3032 rid_array->count,
3033 rids,
3034 &names,
3035 &types,
3036 &result);
3037 if (!NT_STATUS_IS_OK(status)) {
3038 werr = ntstatus_to_werror(status);
3039 goto done;
3041 if (!NT_STATUS_IS_OK(result) &&
3042 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3043 werr = ntstatus_to_werror(result);
3044 goto done;
3046 if (names.count != rid_array->count) {
3047 werr = WERR_BAD_NET_RESP;
3048 goto done;
3050 if (types.count != rid_array->count) {
3051 werr = WERR_BAD_NET_RESP;
3052 goto done;
3055 for (i=0; i < names.count; i++) {
3056 status = add_GROUP_USERS_INFO_X_buffer(ctx,
3057 r->in.level,
3058 names.names[i].string,
3059 rid_array->rids[i].attributes,
3060 r->out.buffer,
3061 &entries_read);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 werr = ntstatus_to_werror(status);
3064 goto done;
3068 *r->out.entries_read = entries_read;
3069 *r->out.total_entries = entries_read;
3071 done:
3072 if (ctx->disable_policy_handle_cache) {
3073 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3074 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3077 return werr;
3080 /****************************************************************
3081 ****************************************************************/
3083 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
3084 struct NetUserGetGroups *r)
3086 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
3089 /****************************************************************
3090 ****************************************************************/
3092 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
3093 struct NetUserSetGroups *r)
3095 struct rpc_pipe_client *pipe_cli = NULL;
3096 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
3097 struct lsa_String lsa_account_name;
3098 struct dom_sid2 *domain_sid = NULL;
3099 struct samr_Ids user_rids, name_types;
3100 struct samr_Ids group_rids;
3101 struct samr_RidWithAttributeArray *rid_array = NULL;
3102 struct lsa_String *lsa_names = NULL;
3104 uint32_t *add_rids = NULL;
3105 uint32_t *del_rids = NULL;
3106 size_t num_add_rids = 0;
3107 size_t num_del_rids = 0;
3109 uint32_t *member_rids = NULL;
3111 struct GROUP_USERS_INFO_0 *i0 = NULL;
3112 struct GROUP_USERS_INFO_1 *i1 = NULL;
3114 int i, k;
3116 NTSTATUS status;
3117 NTSTATUS result = NT_STATUS_OK;
3118 WERROR werr;
3119 struct dcerpc_binding_handle *b = NULL;
3121 ZERO_STRUCT(connect_handle);
3122 ZERO_STRUCT(domain_handle);
3123 ZERO_STRUCT(group_handle);
3125 if (!r->in.buffer) {
3126 return WERR_INVALID_PARAMETER;
3129 switch (r->in.level) {
3130 case 0:
3131 case 1:
3132 break;
3133 default:
3134 return WERR_INVALID_LEVEL;
3137 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3138 &ndr_table_samr,
3139 &pipe_cli);
3140 if (!W_ERROR_IS_OK(werr)) {
3141 goto done;
3144 b = pipe_cli->binding_handle;
3146 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3147 SAMR_ACCESS_ENUM_DOMAINS |
3148 SAMR_ACCESS_LOOKUP_DOMAIN,
3149 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3150 &connect_handle,
3151 &domain_handle,
3152 &domain_sid);
3153 if (!W_ERROR_IS_OK(werr)) {
3154 goto done;
3157 init_lsa_String(&lsa_account_name, r->in.user_name);
3159 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3160 &domain_handle,
3162 &lsa_account_name,
3163 &user_rids,
3164 &name_types,
3165 &result);
3166 if (any_nt_status_not_ok(status, result, &status)) {
3167 werr = ntstatus_to_werror(status);
3168 goto done;
3170 if (user_rids.count != 1) {
3171 werr = WERR_BAD_NET_RESP;
3172 goto done;
3174 if (name_types.count != 1) {
3175 werr = WERR_BAD_NET_RESP;
3176 goto done;
3179 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3180 &domain_handle,
3181 SAMR_USER_ACCESS_GET_GROUPS,
3182 user_rids.ids[0],
3183 &user_handle,
3184 &result);
3185 if (any_nt_status_not_ok(status, result, &status)) {
3186 werr = ntstatus_to_werror(status);
3187 goto done;
3190 switch (r->in.level) {
3191 case 0:
3192 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3193 break;
3194 case 1:
3195 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3196 break;
3199 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3200 if (!lsa_names) {
3201 werr = WERR_NOT_ENOUGH_MEMORY;
3202 goto done;
3205 for (i=0; i < r->in.num_entries; i++) {
3207 switch (r->in.level) {
3208 case 0:
3209 init_lsa_String(&lsa_names[i], i0->grui0_name);
3210 i0++;
3211 break;
3212 case 1:
3213 init_lsa_String(&lsa_names[i], i1->grui1_name);
3214 i1++;
3215 break;
3219 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3220 &domain_handle,
3221 r->in.num_entries,
3222 lsa_names,
3223 &group_rids,
3224 &name_types,
3225 &result);
3226 if (any_nt_status_not_ok(status, result, &status)) {
3227 werr = ntstatus_to_werror(status);
3228 goto done;
3230 if (group_rids.count != r->in.num_entries) {
3231 werr = WERR_BAD_NET_RESP;
3232 goto done;
3234 if (name_types.count != r->in.num_entries) {
3235 werr = WERR_BAD_NET_RESP;
3236 goto done;
3239 member_rids = group_rids.ids;
3241 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3242 &user_handle,
3243 &rid_array,
3244 &result);
3245 if (any_nt_status_not_ok(status, result, &status)) {
3246 werr = ntstatus_to_werror(status);
3247 goto done;
3250 /* add list */
3252 for (i=0; i < r->in.num_entries; i++) {
3253 bool already_member = false;
3254 for (k=0; k < rid_array->count; k++) {
3255 if (member_rids[i] == rid_array->rids[k].rid) {
3256 already_member = true;
3257 break;
3260 if (!already_member) {
3261 if (!add_rid_to_array_unique(ctx,
3262 member_rids[i],
3263 &add_rids, &num_add_rids)) {
3264 werr = WERR_GEN_FAILURE;
3265 goto done;
3270 /* del list */
3272 for (k=0; k < rid_array->count; k++) {
3273 bool keep_member = false;
3274 for (i=0; i < r->in.num_entries; i++) {
3275 if (member_rids[i] == rid_array->rids[k].rid) {
3276 keep_member = true;
3277 break;
3280 if (!keep_member) {
3281 if (!add_rid_to_array_unique(ctx,
3282 rid_array->rids[k].rid,
3283 &del_rids, &num_del_rids)) {
3284 werr = WERR_GEN_FAILURE;
3285 goto done;
3290 /* add list */
3292 for (i=0; i < num_add_rids; i++) {
3293 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3294 &domain_handle,
3295 SAMR_GROUP_ACCESS_ADD_MEMBER,
3296 add_rids[i],
3297 &group_handle,
3298 &result);
3299 if (any_nt_status_not_ok(status, result, &status)) {
3300 werr = ntstatus_to_werror(status);
3301 goto done;
3304 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
3305 &group_handle,
3306 user_rids.ids[0],
3307 7 /* ? */,
3308 &result);
3309 if (any_nt_status_not_ok(status, result, &status)) {
3310 werr = ntstatus_to_werror(status);
3311 goto done;
3314 if (is_valid_policy_hnd(&group_handle)) {
3315 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3319 /* del list */
3321 for (i=0; i < num_del_rids; i++) {
3322 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3323 &domain_handle,
3324 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3325 del_rids[i],
3326 &group_handle,
3327 &result);
3328 if (any_nt_status_not_ok(status, result, &status)) {
3329 werr = ntstatus_to_werror(status);
3330 goto done;
3333 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
3334 &group_handle,
3335 user_rids.ids[0],
3336 &result);
3337 if (any_nt_status_not_ok(status, result, &status)) {
3338 werr = ntstatus_to_werror(status);
3339 goto done;
3342 if (is_valid_policy_hnd(&group_handle)) {
3343 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3347 werr = WERR_OK;
3349 done:
3350 if (is_valid_policy_hnd(&group_handle)) {
3351 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3354 if (ctx->disable_policy_handle_cache) {
3355 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3356 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3359 return werr;
3362 /****************************************************************
3363 ****************************************************************/
3365 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3366 struct NetUserSetGroups *r)
3368 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3371 /****************************************************************
3372 ****************************************************************/
3374 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3375 uint32_t level,
3376 const char *group_name,
3377 uint8_t **buffer,
3378 uint32_t *num_entries)
3380 struct LOCALGROUP_USERS_INFO_0 u0;
3382 switch (level) {
3383 case 0:
3384 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3385 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3387 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3388 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3389 break;
3390 default:
3391 return NT_STATUS_INVALID_INFO_CLASS;
3394 return NT_STATUS_OK;
3397 /****************************************************************
3398 ****************************************************************/
3400 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3401 struct NetUserGetLocalGroups *r)
3403 struct rpc_pipe_client *pipe_cli = NULL;
3404 struct policy_handle connect_handle, domain_handle, user_handle,
3405 builtin_handle;
3406 struct lsa_String lsa_account_name;
3407 struct dom_sid2 *domain_sid = NULL;
3408 struct samr_Ids user_rids, name_types;
3409 struct samr_RidWithAttributeArray *rid_array = NULL;
3410 struct lsa_Strings names;
3411 struct samr_Ids types;
3412 uint32_t *rids = NULL;
3413 size_t num_rids = 0;
3414 struct dom_sid user_sid;
3415 struct lsa_SidArray sid_array;
3416 struct samr_Ids domain_rids;
3417 struct samr_Ids builtin_rids;
3419 int i;
3420 uint32_t entries_read = 0;
3422 NTSTATUS status;
3423 NTSTATUS result = NT_STATUS_OK;
3424 WERROR werr;
3425 struct dcerpc_binding_handle *b = NULL;
3427 ZERO_STRUCT(connect_handle);
3428 ZERO_STRUCT(domain_handle);
3430 if (!r->out.buffer) {
3431 return WERR_INVALID_PARAMETER;
3434 *r->out.buffer = NULL;
3435 *r->out.entries_read = 0;
3436 *r->out.total_entries = 0;
3438 switch (r->in.level) {
3439 case 0:
3440 case 1:
3441 break;
3442 default:
3443 return WERR_INVALID_LEVEL;
3446 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3447 &ndr_table_samr,
3448 &pipe_cli);
3449 if (!W_ERROR_IS_OK(werr)) {
3450 goto done;
3453 b = pipe_cli->binding_handle;
3455 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3456 SAMR_ACCESS_ENUM_DOMAINS |
3457 SAMR_ACCESS_LOOKUP_DOMAIN,
3458 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3459 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3460 &connect_handle,
3461 &domain_handle,
3462 &domain_sid);
3463 if (!W_ERROR_IS_OK(werr)) {
3464 goto done;
3467 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3468 SAMR_ACCESS_ENUM_DOMAINS |
3469 SAMR_ACCESS_LOOKUP_DOMAIN,
3470 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3471 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3472 &connect_handle,
3473 &builtin_handle);
3474 if (!W_ERROR_IS_OK(werr)) {
3475 goto done;
3478 init_lsa_String(&lsa_account_name, r->in.user_name);
3480 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3481 &domain_handle,
3483 &lsa_account_name,
3484 &user_rids,
3485 &name_types,
3486 &result);
3487 if (any_nt_status_not_ok(status, result, &status)) {
3488 werr = ntstatus_to_werror(status);
3489 goto done;
3491 if (user_rids.count != 1) {
3492 werr = WERR_BAD_NET_RESP;
3493 goto done;
3495 if (name_types.count != 1) {
3496 werr = WERR_BAD_NET_RESP;
3497 goto done;
3500 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3501 &domain_handle,
3502 SAMR_USER_ACCESS_GET_GROUPS,
3503 user_rids.ids[0],
3504 &user_handle,
3505 &result);
3506 if (any_nt_status_not_ok(status, result, &status)) {
3507 werr = ntstatus_to_werror(status);
3508 goto done;
3511 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3512 &user_handle,
3513 &rid_array,
3514 &result);
3515 if (any_nt_status_not_ok(status, result, &status)) {
3516 werr = ntstatus_to_werror(status);
3517 goto done;
3520 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3521 werr = WERR_NOT_ENOUGH_MEMORY;
3522 goto done;
3525 sid_array.num_sids = rid_array->count + 1;
3526 sid_array.sids = talloc_array(ctx, struct lsa_SidPtr, sid_array.num_sids);
3527 if (!sid_array.sids) {
3528 werr = WERR_NOT_ENOUGH_MEMORY;
3529 goto done;
3532 sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid);
3533 if (!sid_array.sids[0].sid) {
3534 werr = WERR_NOT_ENOUGH_MEMORY;
3535 goto done;
3538 for (i=0; i < rid_array->count; i++) {
3539 struct dom_sid sid;
3541 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3542 werr = WERR_NOT_ENOUGH_MEMORY;
3543 goto done;
3546 sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid);
3547 if (!sid_array.sids[i+1].sid) {
3548 werr = WERR_NOT_ENOUGH_MEMORY;
3549 goto done;
3553 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3554 &domain_handle,
3555 &sid_array,
3556 &domain_rids,
3557 &result);
3558 if (any_nt_status_not_ok(status, result, &status)) {
3559 werr = ntstatus_to_werror(status);
3560 goto done;
3563 for (i=0; i < domain_rids.count; i++) {
3564 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3565 &rids, &num_rids)) {
3566 werr = WERR_NOT_ENOUGH_MEMORY;
3567 goto done;
3571 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3572 &builtin_handle,
3573 &sid_array,
3574 &builtin_rids,
3575 &result);
3576 if (any_nt_status_not_ok(status, result, &status)) {
3577 werr = ntstatus_to_werror(status);
3578 goto done;
3581 for (i=0; i < builtin_rids.count; i++) {
3582 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3583 &rids, &num_rids)) {
3584 werr = WERR_NOT_ENOUGH_MEMORY;
3585 goto done;
3589 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3590 &builtin_handle,
3591 num_rids,
3592 rids,
3593 &names,
3594 &types,
3595 &result);
3596 if (any_nt_status_not_ok(status, result, &status)) {
3597 werr = ntstatus_to_werror(status);
3598 goto done;
3600 if (names.count != num_rids) {
3601 werr = WERR_BAD_NET_RESP;
3602 goto done;
3604 if (types.count != num_rids) {
3605 werr = WERR_BAD_NET_RESP;
3606 goto done;
3609 for (i=0; i < names.count; i++) {
3610 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3611 r->in.level,
3612 names.names[i].string,
3613 r->out.buffer,
3614 &entries_read);
3615 if (!NT_STATUS_IS_OK(status)) {
3616 werr = ntstatus_to_werror(status);
3617 goto done;
3621 *r->out.entries_read = entries_read;
3622 *r->out.total_entries = entries_read;
3624 done:
3625 if (ctx->disable_policy_handle_cache) {
3626 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3627 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3630 return werr;
3633 /****************************************************************
3634 ****************************************************************/
3636 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3637 struct NetUserGetLocalGroups *r)
3639 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);