vfs_ceph_new: handle case of readlinkat with empty name string
[Samba.git] / source3 / lib / netapi / user.c
bloba7f4c9d7c0121b201fb94ddce6fb1164f43c7e66
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 = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
481 if (!NT_STATUS_IS_OK(status)) {
482 werr = ntstatus_to_werror(status);
483 goto done;
486 uX.usriX_flags |= ACB_NORMAL;
488 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
489 &session_key,
490 &user_handle,
491 &uX);
492 if (!NT_STATUS_IS_OK(status)) {
493 werr = ntstatus_to_werror(status);
494 goto failed;
497 werr = WERR_OK;
498 goto done;
500 failed:
501 dcerpc_samr_DeleteUser(b, talloc_tos(),
502 &user_handle,
503 &result);
505 done:
506 if (is_valid_policy_hnd(&user_handle) && b) {
507 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
510 if (ctx->disable_policy_handle_cache) {
511 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
512 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
515 return werr;
518 /****************************************************************
519 ****************************************************************/
521 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
522 struct NetUserAdd *r)
524 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
527 /****************************************************************
528 ****************************************************************/
530 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
531 struct NetUserDel *r)
533 struct rpc_pipe_client *pipe_cli = NULL;
534 NTSTATUS status, result;
535 WERROR werr;
536 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
537 struct lsa_String lsa_account_name;
538 struct samr_Ids user_rids, name_types;
539 struct dom_sid2 *domain_sid = NULL;
540 struct dom_sid2 user_sid;
541 struct dcerpc_binding_handle *b = NULL;
543 ZERO_STRUCT(connect_handle);
544 ZERO_STRUCT(builtin_handle);
545 ZERO_STRUCT(domain_handle);
546 ZERO_STRUCT(user_handle);
548 werr = libnetapi_open_pipe(ctx, r->in.server_name,
549 &ndr_table_samr,
550 &pipe_cli);
552 if (!W_ERROR_IS_OK(werr)) {
553 goto done;
556 b = pipe_cli->binding_handle;
558 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
559 SAMR_ACCESS_ENUM_DOMAINS |
560 SAMR_ACCESS_LOOKUP_DOMAIN,
561 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
562 &connect_handle,
563 &domain_handle,
564 &domain_sid);
565 if (!W_ERROR_IS_OK(werr)) {
566 goto done;
569 status = dcerpc_samr_OpenDomain(b, talloc_tos(),
570 &connect_handle,
571 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
572 discard_const_p(struct dom_sid, &global_sid_Builtin),
573 &builtin_handle,
574 &result);
575 if (any_nt_status_not_ok(status, result, &status)) {
576 werr = ntstatus_to_werror(status);
577 goto done;
580 init_lsa_String(&lsa_account_name, r->in.user_name);
582 status = dcerpc_samr_LookupNames(b, talloc_tos(),
583 &domain_handle,
585 &lsa_account_name,
586 &user_rids,
587 &name_types,
588 &result);
589 if (any_nt_status_not_ok(status, result, &status)) {
590 werr = ntstatus_to_werror(status);
591 goto done;
593 if (user_rids.count != 1) {
594 werr = WERR_BAD_NET_RESP;
595 goto done;
597 if (name_types.count != 1) {
598 werr = WERR_BAD_NET_RESP;
599 goto done;
602 status = dcerpc_samr_OpenUser(b, talloc_tos(),
603 &domain_handle,
604 SEC_STD_DELETE,
605 user_rids.ids[0],
606 &user_handle,
607 &result);
608 if (any_nt_status_not_ok(status, result, &status)) {
609 werr = ntstatus_to_werror(status);
610 goto done;
613 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
615 status = dcerpc_samr_RemoveMemberFromForeignDomain(b, talloc_tos(),
616 &builtin_handle,
617 &user_sid,
618 &result);
619 if (any_nt_status_not_ok(status, result, &status)) {
620 werr = ntstatus_to_werror(status);
621 goto done;
624 status = dcerpc_samr_DeleteUser(b, talloc_tos(),
625 &user_handle,
626 &result);
627 if (any_nt_status_not_ok(status, result, &status)) {
628 werr = ntstatus_to_werror(status);
629 goto done;
632 werr = WERR_OK;
634 done:
635 if (is_valid_policy_hnd(&user_handle)) {
636 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
639 if (ctx->disable_policy_handle_cache) {
640 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
641 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
642 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
645 return werr;
648 /****************************************************************
649 ****************************************************************/
651 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
652 struct NetUserDel *r)
654 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
657 /****************************************************************
658 ****************************************************************/
660 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
661 struct rpc_pipe_client *pipe_cli,
662 struct policy_handle *domain_handle,
663 struct policy_handle *builtin_handle,
664 const char *user_name,
665 const struct dom_sid *domain_sid,
666 uint32_t rid,
667 uint32_t level,
668 struct samr_UserInfo21 **info21,
669 struct sec_desc_buf **sec_desc,
670 uint32_t *auth_flag_p)
672 NTSTATUS status, result;
674 struct policy_handle user_handle;
675 union samr_UserInfo *user_info = NULL;
676 struct samr_RidWithAttributeArray *rid_array = NULL;
677 uint32_t access_mask = SEC_STD_READ_CONTROL |
678 SAMR_USER_ACCESS_GET_ATTRIBUTES |
679 SAMR_USER_ACCESS_GET_NAME_ETC;
680 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
682 ZERO_STRUCT(user_handle);
684 switch (level) {
685 case 0:
686 break;
687 case 1:
688 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
689 SAMR_USER_ACCESS_GET_GROUPS;
690 break;
691 case 2:
692 case 3:
693 case 4:
694 case 11:
695 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
696 SAMR_USER_ACCESS_GET_GROUPS |
697 SAMR_USER_ACCESS_GET_LOCALE;
698 break;
699 case 10:
700 case 20:
701 case 23:
702 break;
703 default:
704 return NT_STATUS_INVALID_LEVEL;
707 if (level == 0) {
708 return NT_STATUS_OK;
711 status = dcerpc_samr_OpenUser(b, mem_ctx,
712 domain_handle,
713 access_mask,
714 rid,
715 &user_handle,
716 &result);
717 if (any_nt_status_not_ok(status, result, &status)) {
718 goto done;
721 status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
722 &user_handle,
724 &user_info,
725 &result);
726 if (any_nt_status_not_ok(status, result, &status)) {
727 goto done;
730 status = dcerpc_samr_QuerySecurity(b, mem_ctx,
731 &user_handle,
732 SECINFO_DACL,
733 sec_desc,
734 &result);
735 if (any_nt_status_not_ok(status, result, &status)) {
736 goto done;
739 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
741 struct lsa_SidArray sid_array;
742 struct samr_Ids alias_rids;
743 int i;
744 uint32_t auth_flag = 0;
745 struct dom_sid sid;
747 status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
748 &user_handle,
749 &rid_array,
750 &result);
751 if (any_nt_status_not_ok(status, result, &status)) {
752 goto done;
755 sid_array.num_sids = rid_array->count + 1;
756 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
757 sid_array.num_sids);
758 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
760 for (i=0; i<rid_array->count; i++) {
761 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
762 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
763 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
766 sid_compose(&sid, domain_sid, rid);
767 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
768 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
770 status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
771 builtin_handle,
772 &sid_array,
773 &alias_rids,
774 &result);
775 if (any_nt_status_not_ok(status, result, &status)) {
776 goto done;
779 for (i=0; i<alias_rids.count; i++) {
780 switch (alias_rids.ids[i]) {
781 case 550: /* Print Operators */
782 auth_flag |= AF_OP_PRINT;
783 break;
784 case 549: /* Server Operators */
785 auth_flag |= AF_OP_SERVER;
786 break;
787 case 548: /* Account Operators */
788 auth_flag |= AF_OP_ACCOUNTS;
789 break;
790 default:
791 break;
795 if (auth_flag_p) {
796 *auth_flag_p = auth_flag;
800 *info21 = &user_info->info21;
802 done:
803 if (is_valid_policy_hnd(&user_handle)) {
804 dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
807 return status;
810 /****************************************************************
811 ****************************************************************/
813 static uint32_t samr_rid_to_priv_level(uint32_t rid)
815 switch (rid) {
816 case DOMAIN_RID_ADMINISTRATOR:
817 return USER_PRIV_ADMIN;
818 case DOMAIN_RID_GUEST:
819 return USER_PRIV_GUEST;
820 default:
821 return USER_PRIV_USER;
825 /****************************************************************
826 ****************************************************************/
828 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
830 uint32_t fl = UF_SCRIPT; /* god knows why */
832 fl |= ds_acb2uf(acb);
834 return fl;
837 /****************************************************************
838 ****************************************************************/
840 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
841 const struct samr_UserInfo21 *i21,
842 struct USER_INFO_1 *i)
844 ZERO_STRUCTP(i);
845 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
846 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
847 i->usri1_password = NULL;
848 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
849 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
850 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
851 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
852 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
853 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
855 return NT_STATUS_OK;
858 /****************************************************************
859 ****************************************************************/
861 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
862 const struct samr_UserInfo21 *i21,
863 uint32_t auth_flag,
864 struct USER_INFO_2 *i)
866 ZERO_STRUCTP(i);
868 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
869 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
870 i->usri2_password = NULL;
871 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
872 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
873 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
874 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
875 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
876 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
877 i->usri2_auth_flags = auth_flag;
878 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
879 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
880 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
881 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
882 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
883 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
884 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
885 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
886 i->usri2_units_per_week = i21->logon_hours.units_per_week;
887 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
888 i->usri2_bad_pw_count = i21->bad_password_count;
889 i->usri2_num_logons = i21->logon_count;
890 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
891 i->usri2_country_code = i21->country_code;
892 i->usri2_code_page = i21->code_page;
894 return NT_STATUS_OK;
897 /****************************************************************
898 ****************************************************************/
900 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
901 const struct samr_UserInfo21 *i21,
902 uint32_t auth_flag,
903 struct USER_INFO_3 *i)
905 ZERO_STRUCTP(i);
907 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
908 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
909 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
910 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
911 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
912 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
913 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
914 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
915 i->usri3_auth_flags = auth_flag;
916 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
917 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
918 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
919 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
920 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
921 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
922 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
923 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
924 i->usri3_units_per_week = i21->logon_hours.units_per_week;
925 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
926 i->usri3_bad_pw_count = i21->bad_password_count;
927 i->usri3_num_logons = i21->logon_count;
928 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
929 i->usri3_country_code = i21->country_code;
930 i->usri3_code_page = i21->code_page;
931 i->usri3_user_id = i21->rid;
932 i->usri3_primary_group_id = i21->primary_gid;
933 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
934 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
935 i->usri3_password_expired = i21->password_expired;
937 return NT_STATUS_OK;
940 /****************************************************************
941 ****************************************************************/
943 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
944 const struct samr_UserInfo21 *i21,
945 uint32_t auth_flag,
946 struct dom_sid *domain_sid,
947 struct USER_INFO_4 *i)
949 struct dom_sid sid;
951 ZERO_STRUCTP(i);
953 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
954 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
955 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
956 i->usri4_password = NULL;
957 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
958 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
959 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
960 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
961 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
962 i->usri4_auth_flags = auth_flag;
963 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
964 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
965 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
966 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
967 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
968 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
969 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
970 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
971 i->usri4_units_per_week = i21->logon_hours.units_per_week;
972 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
973 i->usri4_bad_pw_count = i21->bad_password_count;
974 i->usri4_num_logons = i21->logon_count;
975 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
976 i->usri4_country_code = i21->country_code;
977 i->usri4_code_page = i21->code_page;
978 if (!sid_compose(&sid, domain_sid, i21->rid)) {
979 return NT_STATUS_NO_MEMORY;
981 i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
982 i->usri4_primary_group_id = i21->primary_gid;
983 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
984 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
985 i->usri4_password_expired = i21->password_expired;
987 return NT_STATUS_OK;
990 /****************************************************************
991 ****************************************************************/
993 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
994 const struct samr_UserInfo21 *i21,
995 struct USER_INFO_10 *i)
997 ZERO_STRUCTP(i);
999 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
1000 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
1001 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
1002 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1003 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1005 return NT_STATUS_OK;
1008 /****************************************************************
1009 ****************************************************************/
1011 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
1012 const struct samr_UserInfo21 *i21,
1013 uint32_t auth_flag,
1014 struct USER_INFO_11 *i)
1016 ZERO_STRUCTP(i);
1018 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
1019 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
1020 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
1021 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1022 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1023 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
1024 i->usri11_auth_flags = auth_flag;
1025 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1026 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1027 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1028 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
1029 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
1030 i->usri11_bad_pw_count = i21->bad_password_count;
1031 i->usri11_num_logons = i21->logon_count;
1032 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1033 i->usri11_country_code = i21->country_code;
1034 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1035 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1036 i->usri11_units_per_week = i21->logon_hours.units_per_week;
1037 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1038 i->usri11_code_page = i21->code_page;
1040 return NT_STATUS_OK;
1043 /****************************************************************
1044 ****************************************************************/
1046 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
1047 const struct samr_UserInfo21 *i21,
1048 struct USER_INFO_20 *i)
1050 ZERO_STRUCTP(i);
1052 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1053 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1054 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1055 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1056 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1057 i->usri20_user_id = i21->rid;
1059 return NT_STATUS_OK;
1062 /****************************************************************
1063 ****************************************************************/
1065 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1066 const struct samr_UserInfo21 *i21,
1067 struct dom_sid *domain_sid,
1068 struct USER_INFO_23 *i)
1070 struct dom_sid sid;
1072 ZERO_STRUCTP(i);
1074 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1075 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1076 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1077 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1078 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1079 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1080 return NT_STATUS_NO_MEMORY;
1082 i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1084 return NT_STATUS_OK;
1087 /****************************************************************
1088 ****************************************************************/
1090 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1091 struct rpc_pipe_client *pipe_cli,
1092 struct dom_sid *domain_sid,
1093 struct policy_handle *domain_handle,
1094 struct policy_handle *builtin_handle,
1095 const char *user_name,
1096 uint32_t rid,
1097 uint32_t level,
1098 uint8_t **buffer,
1099 uint32_t *num_entries)
1101 NTSTATUS status;
1103 struct samr_UserInfo21 *info21 = NULL;
1104 struct sec_desc_buf *sec_desc = NULL;
1105 uint32_t auth_flag = 0;
1107 struct USER_INFO_0 info0;
1108 struct USER_INFO_1 info1;
1109 struct USER_INFO_2 info2;
1110 struct USER_INFO_3 info3;
1111 struct USER_INFO_4 info4;
1112 struct USER_INFO_10 info10;
1113 struct USER_INFO_11 info11;
1114 struct USER_INFO_20 info20;
1115 struct USER_INFO_23 info23;
1117 switch (level) {
1118 case 0:
1119 case 1:
1120 case 2:
1121 case 3:
1122 case 4:
1123 case 10:
1124 case 11:
1125 case 20:
1126 case 23:
1127 break;
1128 default:
1129 return NT_STATUS_INVALID_LEVEL;
1132 if (level == 0) {
1133 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1134 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1136 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1137 (struct USER_INFO_0 **)buffer, num_entries);
1139 return NT_STATUS_OK;
1142 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1143 domain_handle,
1144 builtin_handle,
1145 user_name,
1146 domain_sid,
1147 rid,
1148 level,
1149 &info21,
1150 &sec_desc,
1151 &auth_flag);
1153 if (!NT_STATUS_IS_OK(status)) {
1154 goto done;
1157 switch (level) {
1158 case 1:
1159 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1160 NT_STATUS_NOT_OK_RETURN(status);
1162 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1163 (struct USER_INFO_1 **)buffer, num_entries);
1165 break;
1166 case 2:
1167 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1168 NT_STATUS_NOT_OK_RETURN(status);
1170 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1171 (struct USER_INFO_2 **)buffer, num_entries);
1173 break;
1174 case 3:
1175 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1176 NT_STATUS_NOT_OK_RETURN(status);
1178 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1179 (struct USER_INFO_3 **)buffer, num_entries);
1181 break;
1182 case 4:
1183 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1184 NT_STATUS_NOT_OK_RETURN(status);
1186 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1187 (struct USER_INFO_4 **)buffer, num_entries);
1189 break;
1190 case 10:
1191 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1192 NT_STATUS_NOT_OK_RETURN(status);
1194 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1195 (struct USER_INFO_10 **)buffer, num_entries);
1197 break;
1198 case 11:
1199 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1200 NT_STATUS_NOT_OK_RETURN(status);
1202 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1203 (struct USER_INFO_11 **)buffer, num_entries);
1205 break;
1206 case 20:
1207 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1208 NT_STATUS_NOT_OK_RETURN(status);
1210 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1211 (struct USER_INFO_20 **)buffer, num_entries);
1213 break;
1214 case 23:
1215 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1216 NT_STATUS_NOT_OK_RETURN(status);
1218 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1219 (struct USER_INFO_23 **)buffer, num_entries);
1220 break;
1221 default:
1222 return NT_STATUS_INVALID_LEVEL;
1225 done:
1226 return status;
1229 /****************************************************************
1230 ****************************************************************/
1232 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1233 struct NetUserEnum *r)
1235 struct rpc_pipe_client *pipe_cli = NULL;
1236 struct policy_handle connect_handle;
1237 struct dom_sid2 *domain_sid = NULL;
1238 struct policy_handle domain_handle, builtin_handle;
1239 struct samr_SamArray *sam = NULL;
1240 uint32_t filter = ACB_NORMAL;
1241 int i;
1242 uint32_t entries_read = 0;
1244 NTSTATUS status;
1245 NTSTATUS result = NT_STATUS_OK;
1246 WERROR werr;
1247 struct dcerpc_binding_handle *b = NULL;
1249 ZERO_STRUCT(connect_handle);
1250 ZERO_STRUCT(domain_handle);
1251 ZERO_STRUCT(builtin_handle);
1253 if (!r->out.buffer) {
1254 return WERR_INVALID_PARAMETER;
1257 *r->out.buffer = NULL;
1258 *r->out.entries_read = 0;
1260 switch (r->in.level) {
1261 case 0:
1262 case 1:
1263 case 2:
1264 case 3:
1265 case 4:
1266 case 10:
1267 case 11:
1268 case 20:
1269 case 23:
1270 break;
1271 default:
1272 return WERR_INVALID_LEVEL;
1275 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1276 &ndr_table_samr,
1277 &pipe_cli);
1278 if (!W_ERROR_IS_OK(werr)) {
1279 goto done;
1282 b = pipe_cli->binding_handle;
1284 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1285 SAMR_ACCESS_ENUM_DOMAINS |
1286 SAMR_ACCESS_LOOKUP_DOMAIN,
1287 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1288 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1289 &connect_handle,
1290 &builtin_handle);
1291 if (!W_ERROR_IS_OK(werr)) {
1292 goto done;
1295 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1296 SAMR_ACCESS_ENUM_DOMAINS |
1297 SAMR_ACCESS_LOOKUP_DOMAIN,
1298 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1299 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1300 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1301 &connect_handle,
1302 &domain_handle,
1303 &domain_sid);
1304 if (!W_ERROR_IS_OK(werr)) {
1305 goto done;
1308 switch (r->in.filter) {
1309 case FILTER_NORMAL_ACCOUNT:
1310 filter = ACB_NORMAL;
1311 break;
1312 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1313 filter = ACB_TEMPDUP;
1314 break;
1315 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1316 filter = ACB_DOMTRUST;
1317 break;
1318 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1319 filter = ACB_WSTRUST;
1320 break;
1321 case FILTER_SERVER_TRUST_ACCOUNT:
1322 filter = ACB_SVRTRUST;
1323 break;
1324 default:
1325 break;
1328 status = dcerpc_samr_EnumDomainUsers(b,
1329 ctx,
1330 &domain_handle,
1331 r->in.resume_handle,
1332 filter,
1333 &sam,
1334 r->in.prefmaxlen,
1335 &entries_read,
1336 &result);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 werr = ntstatus_to_werror(status);
1339 goto done;
1341 werr = ntstatus_to_werror(result);
1342 if (NT_STATUS_IS_ERR(result)) {
1343 goto done;
1346 for (i=0; i < sam->count; i++) {
1348 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1349 domain_sid,
1350 &domain_handle,
1351 &builtin_handle,
1352 sam->entries[i].name.string,
1353 sam->entries[i].idx,
1354 r->in.level,
1355 r->out.buffer,
1356 r->out.entries_read);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 werr = ntstatus_to_werror(status);
1359 goto done;
1363 done:
1364 /* if last query */
1365 if (NT_STATUS_IS_OK(result) ||
1366 NT_STATUS_IS_ERR(result)) {
1368 if (ctx->disable_policy_handle_cache) {
1369 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1370 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1371 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1375 return werr;
1378 /****************************************************************
1379 ****************************************************************/
1381 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1382 struct NetUserEnum *r)
1384 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1387 /****************************************************************
1388 ****************************************************************/
1390 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1391 struct samr_DispInfoGeneral *info,
1392 uint32_t *entries_read,
1393 void **buffer)
1395 struct NET_DISPLAY_USER *user = NULL;
1396 int i;
1398 user = talloc_zero_array(mem_ctx,
1399 struct NET_DISPLAY_USER,
1400 info->count);
1401 W_ERROR_HAVE_NO_MEMORY(user);
1403 for (i = 0; i < info->count; i++) {
1404 user[i].usri1_name = talloc_strdup(mem_ctx,
1405 info->entries[i].account_name.string);
1406 user[i].usri1_comment = talloc_strdup(mem_ctx,
1407 info->entries[i].description.string);
1408 user[i].usri1_flags =
1409 info->entries[i].acct_flags;
1410 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1411 info->entries[i].full_name.string);
1412 user[i].usri1_user_id =
1413 info->entries[i].rid;
1414 user[i].usri1_next_index =
1415 info->entries[i].idx;
1417 if (!user[i].usri1_name) {
1418 return WERR_NOT_ENOUGH_MEMORY;
1422 *buffer = talloc_memdup(mem_ctx, user,
1423 sizeof(struct NET_DISPLAY_USER) * info->count);
1424 W_ERROR_HAVE_NO_MEMORY(*buffer);
1426 *entries_read = info->count;
1428 return WERR_OK;
1431 /****************************************************************
1432 ****************************************************************/
1434 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1435 struct samr_DispInfoFull *info,
1436 uint32_t *entries_read,
1437 void **buffer)
1439 struct NET_DISPLAY_MACHINE *machine = NULL;
1440 int i;
1442 machine = talloc_zero_array(mem_ctx,
1443 struct NET_DISPLAY_MACHINE,
1444 info->count);
1445 W_ERROR_HAVE_NO_MEMORY(machine);
1447 for (i = 0; i < info->count; i++) {
1448 machine[i].usri2_name = talloc_strdup(mem_ctx,
1449 info->entries[i].account_name.string);
1450 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1451 info->entries[i].description.string);
1452 machine[i].usri2_flags =
1453 info->entries[i].acct_flags;
1454 machine[i].usri2_user_id =
1455 info->entries[i].rid;
1456 machine[i].usri2_next_index =
1457 info->entries[i].idx;
1459 if (!machine[i].usri2_name) {
1460 return WERR_NOT_ENOUGH_MEMORY;
1464 *buffer = talloc_memdup(mem_ctx, machine,
1465 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1466 W_ERROR_HAVE_NO_MEMORY(*buffer);
1468 *entries_read = info->count;
1470 return WERR_OK;
1473 /****************************************************************
1474 ****************************************************************/
1476 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1477 struct samr_DispInfoFullGroups *info,
1478 uint32_t *entries_read,
1479 void **buffer)
1481 struct NET_DISPLAY_GROUP *group = NULL;
1482 int i;
1484 group = talloc_zero_array(mem_ctx,
1485 struct NET_DISPLAY_GROUP,
1486 info->count);
1487 W_ERROR_HAVE_NO_MEMORY(group);
1489 for (i = 0; i < info->count; i++) {
1490 group[i].grpi3_name = talloc_strdup(mem_ctx,
1491 info->entries[i].account_name.string);
1492 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1493 info->entries[i].description.string);
1494 group[i].grpi3_group_id =
1495 info->entries[i].rid;
1496 group[i].grpi3_attributes =
1497 info->entries[i].acct_flags;
1498 group[i].grpi3_next_index =
1499 info->entries[i].idx;
1501 if (!group[i].grpi3_name) {
1502 return WERR_NOT_ENOUGH_MEMORY;
1506 *buffer = talloc_memdup(mem_ctx, group,
1507 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1508 W_ERROR_HAVE_NO_MEMORY(*buffer);
1510 *entries_read = info->count;
1512 return WERR_OK;
1516 /****************************************************************
1517 ****************************************************************/
1519 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1520 union samr_DispInfo *info,
1521 uint32_t level,
1522 uint32_t *entries_read,
1523 void **buffer)
1525 switch (level) {
1526 case 1:
1527 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1528 &info->info1,
1529 entries_read,
1530 buffer);
1531 case 2:
1532 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1533 &info->info2,
1534 entries_read,
1535 buffer);
1536 case 3:
1537 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1538 &info->info3,
1539 entries_read,
1540 buffer);
1541 default:
1542 break;
1545 return WERR_INVALID_LEVEL;
1548 /****************************************************************
1549 ****************************************************************/
1551 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1552 struct NetQueryDisplayInformation *r)
1554 struct rpc_pipe_client *pipe_cli = NULL;
1555 struct policy_handle connect_handle;
1556 struct dom_sid2 *domain_sid = NULL;
1557 struct policy_handle domain_handle;
1558 union samr_DispInfo info;
1559 struct dcerpc_binding_handle *b = NULL;
1561 uint32_t total_size = 0;
1562 uint32_t returned_size = 0;
1564 NTSTATUS status;
1565 NTSTATUS result = NT_STATUS_OK;
1566 WERROR werr;
1567 WERROR werr_tmp;
1569 *r->out.entries_read = 0;
1571 ZERO_STRUCT(connect_handle);
1572 ZERO_STRUCT(domain_handle);
1574 switch (r->in.level) {
1575 case 1:
1576 case 2:
1577 case 3:
1578 break;
1579 default:
1580 return WERR_INVALID_LEVEL;
1583 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1584 &ndr_table_samr,
1585 &pipe_cli);
1586 if (!W_ERROR_IS_OK(werr)) {
1587 goto done;
1590 b = pipe_cli->binding_handle;
1592 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1593 SAMR_ACCESS_ENUM_DOMAINS |
1594 SAMR_ACCESS_LOOKUP_DOMAIN,
1595 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1596 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1597 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1598 &connect_handle,
1599 &domain_handle,
1600 &domain_sid);
1601 if (!W_ERROR_IS_OK(werr)) {
1602 goto done;
1605 status = dcerpc_samr_QueryDisplayInfo2(b,
1606 ctx,
1607 &domain_handle,
1608 r->in.level,
1609 r->in.idx,
1610 r->in.entries_requested,
1611 r->in.prefmaxlen,
1612 &total_size,
1613 &returned_size,
1614 &info,
1615 &result);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 werr = ntstatus_to_werror(status);
1618 goto done;
1620 werr = ntstatus_to_werror(result);
1621 if (NT_STATUS_IS_ERR(result)) {
1622 goto done;
1625 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1626 r->in.level,
1627 r->out.entries_read,
1628 r->out.buffer);
1629 if (!W_ERROR_IS_OK(werr_tmp)) {
1630 werr = werr_tmp;
1632 done:
1633 /* if last query */
1634 if (NT_STATUS_IS_OK(result) ||
1635 NT_STATUS_IS_ERR(result)) {
1637 if (ctx->disable_policy_handle_cache) {
1638 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1639 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1643 return werr;
1647 /****************************************************************
1648 ****************************************************************/
1651 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1652 struct NetQueryDisplayInformation *r)
1654 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1657 /****************************************************************
1658 ****************************************************************/
1660 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1661 struct NetUserChangePassword *r)
1663 return WERR_NOT_SUPPORTED;
1666 /****************************************************************
1667 ****************************************************************/
1669 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1670 struct NetUserChangePassword *r)
1672 return WERR_NOT_SUPPORTED;
1675 /****************************************************************
1676 ****************************************************************/
1678 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1679 struct NetUserGetInfo *r)
1681 struct rpc_pipe_client *pipe_cli = NULL;
1682 NTSTATUS status, result;
1683 WERROR werr;
1685 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1686 struct lsa_String lsa_account_name;
1687 struct dom_sid2 *domain_sid = NULL;
1688 struct samr_Ids user_rids, name_types;
1689 uint32_t num_entries = 0;
1690 struct dcerpc_binding_handle *b = NULL;
1692 ZERO_STRUCT(connect_handle);
1693 ZERO_STRUCT(domain_handle);
1694 ZERO_STRUCT(builtin_handle);
1695 ZERO_STRUCT(user_handle);
1697 if (!r->out.buffer) {
1698 return WERR_INVALID_PARAMETER;
1701 switch (r->in.level) {
1702 case 0:
1703 case 1:
1704 case 2:
1705 case 3:
1706 case 4:
1707 case 10:
1708 case 11:
1709 case 20:
1710 case 23:
1711 break;
1712 default:
1713 werr = WERR_INVALID_LEVEL;
1714 goto done;
1717 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1718 &ndr_table_samr,
1719 &pipe_cli);
1720 if (!W_ERROR_IS_OK(werr)) {
1721 goto done;
1724 b = pipe_cli->binding_handle;
1726 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1727 SAMR_ACCESS_ENUM_DOMAINS |
1728 SAMR_ACCESS_LOOKUP_DOMAIN,
1729 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1730 &connect_handle,
1731 &domain_handle,
1732 &domain_sid);
1733 if (!W_ERROR_IS_OK(werr)) {
1734 goto done;
1737 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1738 SAMR_ACCESS_ENUM_DOMAINS |
1739 SAMR_ACCESS_LOOKUP_DOMAIN,
1740 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1741 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1742 &connect_handle,
1743 &builtin_handle);
1744 if (!W_ERROR_IS_OK(werr)) {
1745 goto done;
1748 init_lsa_String(&lsa_account_name, r->in.user_name);
1750 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1751 &domain_handle,
1753 &lsa_account_name,
1754 &user_rids,
1755 &name_types,
1756 &result);
1757 if (any_nt_status_not_ok(status, result, &status)) {
1758 werr = ntstatus_to_werror(status);
1759 goto done;
1761 if (user_rids.count != 1) {
1762 werr = WERR_BAD_NET_RESP;
1763 goto done;
1765 if (name_types.count != 1) {
1766 werr = WERR_BAD_NET_RESP;
1767 goto done;
1770 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1771 domain_sid,
1772 &domain_handle,
1773 &builtin_handle,
1774 r->in.user_name,
1775 user_rids.ids[0],
1776 r->in.level,
1777 r->out.buffer,
1778 &num_entries);
1779 if (!NT_STATUS_IS_OK(status)) {
1780 werr = ntstatus_to_werror(status);
1781 goto done;
1784 done:
1785 if (is_valid_policy_hnd(&user_handle) && b) {
1786 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1789 if (ctx->disable_policy_handle_cache) {
1790 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1791 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1794 return werr;
1797 /****************************************************************
1798 ****************************************************************/
1800 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1801 struct NetUserGetInfo *r)
1803 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1806 /****************************************************************
1807 ****************************************************************/
1809 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1810 struct NetUserSetInfo *r)
1812 struct rpc_pipe_client *pipe_cli = NULL;
1813 NTSTATUS status, result;
1814 WERROR werr;
1816 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1817 struct lsa_String lsa_account_name;
1818 struct dom_sid2 *domain_sid = NULL;
1819 struct samr_Ids user_rids, name_types;
1820 uint32_t user_mask = 0;
1822 struct USER_INFO_X uX;
1823 struct dcerpc_binding_handle *b = NULL;
1824 DATA_BLOB session_key;
1826 ZERO_STRUCT(connect_handle);
1827 ZERO_STRUCT(domain_handle);
1828 ZERO_STRUCT(builtin_handle);
1829 ZERO_STRUCT(user_handle);
1831 if (!r->in.buffer) {
1832 return WERR_INVALID_PARAMETER;
1835 switch (r->in.level) {
1836 case 0:
1837 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1838 break;
1839 case 1003:
1840 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1841 break;
1842 case 1006:
1843 case 1007:
1844 case 1009:
1845 case 1011:
1846 case 1014:
1847 case 1052:
1848 case 1053:
1849 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1850 break;
1851 case 1012:
1852 case 1024:
1853 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1854 break;
1855 case 1051:
1856 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1857 SAMR_USER_ACCESS_GET_GROUPS;
1858 break;
1859 case 3:
1860 user_mask = SEC_STD_READ_CONTROL |
1861 SEC_STD_WRITE_DAC |
1862 SAMR_USER_ACCESS_GET_GROUPS |
1863 SAMR_USER_ACCESS_SET_PASSWORD |
1864 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1865 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1866 SAMR_USER_ACCESS_SET_LOC_COM;
1867 break;
1868 case 1:
1869 case 2:
1870 case 4:
1871 case 21:
1872 case 22:
1873 case 1005:
1874 case 1008:
1875 case 1010:
1876 case 1017:
1877 case 1020:
1878 werr = WERR_NOT_SUPPORTED;
1879 goto done;
1880 default:
1881 werr = WERR_INVALID_LEVEL;
1882 goto done;
1885 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1886 &ndr_table_samr,
1887 &pipe_cli);
1888 if (!W_ERROR_IS_OK(werr)) {
1889 goto done;
1892 b = pipe_cli->binding_handle;
1894 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1895 SAMR_ACCESS_ENUM_DOMAINS |
1896 SAMR_ACCESS_LOOKUP_DOMAIN,
1897 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1898 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1899 &connect_handle,
1900 &domain_handle,
1901 &domain_sid);
1902 if (!W_ERROR_IS_OK(werr)) {
1903 goto done;
1906 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1907 SAMR_ACCESS_ENUM_DOMAINS |
1908 SAMR_ACCESS_LOOKUP_DOMAIN,
1909 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1910 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1911 &connect_handle,
1912 &builtin_handle);
1913 if (!W_ERROR_IS_OK(werr)) {
1914 goto done;
1917 init_lsa_String(&lsa_account_name, r->in.user_name);
1919 status = dcerpc_samr_LookupNames(b, talloc_tos(),
1920 &domain_handle,
1922 &lsa_account_name,
1923 &user_rids,
1924 &name_types,
1925 &result);
1926 if (any_nt_status_not_ok(status, result, &status)) {
1927 werr = ntstatus_to_werror(status);
1928 goto done;
1930 if (user_rids.count != 1) {
1931 werr = WERR_BAD_NET_RESP;
1932 goto done;
1934 if (name_types.count != 1) {
1935 werr = WERR_BAD_NET_RESP;
1936 goto done;
1939 status = dcerpc_samr_OpenUser(b, talloc_tos(),
1940 &domain_handle,
1941 user_mask,
1942 user_rids.ids[0],
1943 &user_handle,
1944 &result);
1945 if (any_nt_status_not_ok(status, result, &status)) {
1946 werr = ntstatus_to_werror(status);
1947 goto done;
1950 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1951 if (!NT_STATUS_IS_OK(status)) {
1952 werr = ntstatus_to_werror(status);
1953 goto done;
1956 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
1957 if (!NT_STATUS_IS_OK(status)) {
1958 werr = ntstatus_to_werror(status);
1959 goto done;
1962 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1963 &session_key,
1964 &user_handle,
1965 &uX);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 werr = ntstatus_to_werror(status);
1968 goto done;
1971 werr = WERR_OK;
1973 done:
1974 if (is_valid_policy_hnd(&user_handle) && b) {
1975 dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1978 if (ctx->disable_policy_handle_cache) {
1979 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1980 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1981 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1984 return werr;
1987 /****************************************************************
1988 ****************************************************************/
1990 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1991 struct NetUserSetInfo *r)
1993 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1996 /****************************************************************
1997 ****************************************************************/
1999 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2000 struct rpc_pipe_client *pipe_cli,
2001 struct policy_handle *domain_handle,
2002 struct samr_DomInfo1 *info1,
2003 struct samr_DomInfo3 *info3,
2004 struct samr_DomInfo5 *info5,
2005 struct samr_DomInfo6 *info6,
2006 struct samr_DomInfo7 *info7,
2007 struct samr_DomInfo12 *info12)
2009 NTSTATUS status, result;
2010 union samr_DomainInfo *dom_info = NULL;
2011 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2013 if (info1) {
2014 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2015 domain_handle,
2017 &dom_info,
2018 &result);
2019 NT_STATUS_NOT_OK_RETURN(status);
2020 NT_STATUS_NOT_OK_RETURN(result);
2022 *info1 = dom_info->info1;
2025 if (info3) {
2026 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2027 domain_handle,
2029 &dom_info,
2030 &result);
2031 NT_STATUS_NOT_OK_RETURN(status);
2032 NT_STATUS_NOT_OK_RETURN(result);
2034 *info3 = dom_info->info3;
2037 if (info5) {
2038 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2039 domain_handle,
2041 &dom_info,
2042 &result);
2043 NT_STATUS_NOT_OK_RETURN(status);
2044 NT_STATUS_NOT_OK_RETURN(result);
2046 *info5 = dom_info->info5;
2049 if (info6) {
2050 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2051 domain_handle,
2053 &dom_info,
2054 &result);
2055 NT_STATUS_NOT_OK_RETURN(status);
2056 NT_STATUS_NOT_OK_RETURN(result);
2058 *info6 = dom_info->info6;
2061 if (info7) {
2062 status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2063 domain_handle,
2065 &dom_info,
2066 &result);
2067 NT_STATUS_NOT_OK_RETURN(status);
2068 NT_STATUS_NOT_OK_RETURN(result);
2070 *info7 = dom_info->info7;
2073 if (info12) {
2074 status = dcerpc_samr_QueryDomainInfo2(b, mem_ctx,
2075 domain_handle,
2077 &dom_info,
2078 &result);
2079 NT_STATUS_NOT_OK_RETURN(status);
2080 NT_STATUS_NOT_OK_RETURN(result);
2082 *info12 = dom_info->info12;
2085 return NT_STATUS_OK;
2088 /****************************************************************
2089 ****************************************************************/
2091 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
2092 struct rpc_pipe_client *pipe_cli,
2093 struct policy_handle *domain_handle,
2094 struct USER_MODALS_INFO_0 *info0)
2096 NTSTATUS status;
2097 struct samr_DomInfo1 dom_info1;
2098 struct samr_DomInfo3 dom_info3;
2100 ZERO_STRUCTP(info0);
2102 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2103 pipe_cli,
2104 domain_handle,
2105 &dom_info1,
2106 &dom_info3,
2107 NULL,
2108 NULL,
2109 NULL,
2110 NULL);
2111 NT_STATUS_NOT_OK_RETURN(status);
2113 info0->usrmod0_min_passwd_len =
2114 dom_info1.min_password_length;
2115 info0->usrmod0_max_passwd_age =
2116 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2117 info0->usrmod0_min_passwd_age =
2118 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2119 info0->usrmod0_password_hist_len =
2120 dom_info1.password_history_length;
2122 info0->usrmod0_force_logoff =
2123 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2125 return NT_STATUS_OK;
2128 /****************************************************************
2129 ****************************************************************/
2131 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2132 struct rpc_pipe_client *pipe_cli,
2133 struct policy_handle *domain_handle,
2134 struct USER_MODALS_INFO_1 *info1)
2136 NTSTATUS status;
2137 struct samr_DomInfo6 dom_info6;
2138 struct samr_DomInfo7 dom_info7;
2140 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2141 pipe_cli,
2142 domain_handle,
2143 NULL,
2144 NULL,
2145 NULL,
2146 &dom_info6,
2147 &dom_info7,
2148 NULL);
2149 NT_STATUS_NOT_OK_RETURN(status);
2151 info1->usrmod1_primary =
2152 talloc_strdup(mem_ctx, dom_info6.primary.string);
2154 info1->usrmod1_role = dom_info7.role;
2156 return NT_STATUS_OK;
2159 /****************************************************************
2160 ****************************************************************/
2162 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2163 struct rpc_pipe_client *pipe_cli,
2164 struct policy_handle *domain_handle,
2165 struct dom_sid *domain_sid,
2166 struct USER_MODALS_INFO_2 *info2)
2168 NTSTATUS status;
2169 struct samr_DomInfo5 dom_info5;
2171 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2172 pipe_cli,
2173 domain_handle,
2174 NULL,
2175 NULL,
2176 &dom_info5,
2177 NULL,
2178 NULL,
2179 NULL);
2180 NT_STATUS_NOT_OK_RETURN(status);
2182 info2->usrmod2_domain_name =
2183 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2184 info2->usrmod2_domain_id =
2185 (struct domsid *)dom_sid_dup(mem_ctx, domain_sid);
2187 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2188 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2190 return NT_STATUS_OK;
2193 /****************************************************************
2194 ****************************************************************/
2196 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2197 struct rpc_pipe_client *pipe_cli,
2198 struct policy_handle *domain_handle,
2199 struct USER_MODALS_INFO_3 *info3)
2201 NTSTATUS status;
2202 struct samr_DomInfo12 dom_info12;
2204 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2205 pipe_cli,
2206 domain_handle,
2207 NULL,
2208 NULL,
2209 NULL,
2210 NULL,
2211 NULL,
2212 &dom_info12);
2213 NT_STATUS_NOT_OK_RETURN(status);
2215 info3->usrmod3_lockout_duration =
2216 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2217 info3->usrmod3_lockout_observation_window =
2218 nt_time_to_unix_abs(&dom_info12.lockout_window);
2219 info3->usrmod3_lockout_threshold =
2220 dom_info12.lockout_threshold;
2222 return NT_STATUS_OK;
2225 /****************************************************************
2226 ****************************************************************/
2228 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2229 struct rpc_pipe_client *pipe_cli,
2230 uint32_t level,
2231 struct policy_handle *domain_handle,
2232 struct dom_sid *domain_sid,
2233 uint8_t **buffer)
2235 NTSTATUS status;
2237 struct USER_MODALS_INFO_0 info0;
2238 struct USER_MODALS_INFO_1 info1;
2239 struct USER_MODALS_INFO_2 info2;
2240 struct USER_MODALS_INFO_3 info3;
2242 if (!buffer) {
2243 return ERROR_INSUFFICIENT_BUFFER;
2246 switch (level) {
2247 case 0:
2248 status = query_USER_MODALS_INFO_0(mem_ctx,
2249 pipe_cli,
2250 domain_handle,
2251 &info0);
2252 NT_STATUS_NOT_OK_RETURN(status);
2254 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2255 sizeof(info0));
2256 break;
2258 case 1:
2259 status = query_USER_MODALS_INFO_1(mem_ctx,
2260 pipe_cli,
2261 domain_handle,
2262 &info1);
2263 NT_STATUS_NOT_OK_RETURN(status);
2265 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2266 sizeof(info1));
2267 break;
2268 case 2:
2269 status = query_USER_MODALS_INFO_2(mem_ctx,
2270 pipe_cli,
2271 domain_handle,
2272 domain_sid,
2273 &info2);
2274 NT_STATUS_NOT_OK_RETURN(status);
2276 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2277 sizeof(info2));
2278 break;
2279 case 3:
2280 status = query_USER_MODALS_INFO_3(mem_ctx,
2281 pipe_cli,
2282 domain_handle,
2283 &info3);
2284 NT_STATUS_NOT_OK_RETURN(status);
2286 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2287 sizeof(info3));
2288 break;
2289 default:
2290 break;
2293 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2295 return NT_STATUS_OK;
2298 /****************************************************************
2299 ****************************************************************/
2301 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2302 struct NetUserModalsGet *r)
2304 struct rpc_pipe_client *pipe_cli = NULL;
2305 NTSTATUS status;
2306 WERROR werr;
2308 struct policy_handle connect_handle, domain_handle;
2309 struct dom_sid2 *domain_sid = NULL;
2310 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2312 ZERO_STRUCT(connect_handle);
2313 ZERO_STRUCT(domain_handle);
2315 if (!r->out.buffer) {
2316 return WERR_INVALID_PARAMETER;
2319 switch (r->in.level) {
2320 case 0:
2321 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2322 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2323 break;
2324 case 1:
2325 case 2:
2326 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2327 break;
2328 case 3:
2329 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2330 break;
2331 default:
2332 werr = WERR_INVALID_LEVEL;
2333 goto done;
2336 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2337 &ndr_table_samr,
2338 &pipe_cli);
2339 if (!W_ERROR_IS_OK(werr)) {
2340 goto done;
2343 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2344 SAMR_ACCESS_ENUM_DOMAINS |
2345 SAMR_ACCESS_LOOKUP_DOMAIN,
2346 access_mask,
2347 &connect_handle,
2348 &domain_handle,
2349 &domain_sid);
2350 if (!W_ERROR_IS_OK(werr)) {
2351 goto done;
2354 /* 0: 1 + 3 */
2355 /* 1: 6 + 7 */
2356 /* 2: 5 */
2357 /* 3: 12 (DomainInfo2) */
2359 status = query_USER_MODALS_INFO_to_buffer(ctx,
2360 pipe_cli,
2361 r->in.level,
2362 &domain_handle,
2363 domain_sid,
2364 r->out.buffer);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 werr = ntstatus_to_werror(status);
2367 goto done;
2370 done:
2371 if (ctx->disable_policy_handle_cache) {
2372 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2373 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2376 return werr;
2379 /****************************************************************
2380 ****************************************************************/
2382 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2383 struct NetUserModalsGet *r)
2385 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2388 /****************************************************************
2389 ****************************************************************/
2391 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2392 struct rpc_pipe_client *pipe_cli,
2393 struct policy_handle *domain_handle,
2394 struct samr_DomInfo1 *info1,
2395 struct samr_DomInfo3 *info3,
2396 struct samr_DomInfo12 *info12)
2398 NTSTATUS status, result;
2399 union samr_DomainInfo dom_info;
2400 struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2402 if (info1) {
2404 ZERO_STRUCT(dom_info);
2406 dom_info.info1 = *info1;
2408 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2409 domain_handle,
2411 &dom_info,
2412 &result);
2413 NT_STATUS_NOT_OK_RETURN(status);
2414 NT_STATUS_NOT_OK_RETURN(result);
2417 if (info3) {
2419 ZERO_STRUCT(dom_info);
2421 dom_info.info3 = *info3;
2423 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2424 domain_handle,
2426 &dom_info,
2427 &result);
2429 NT_STATUS_NOT_OK_RETURN(status);
2430 NT_STATUS_NOT_OK_RETURN(result);
2433 if (info12) {
2435 ZERO_STRUCT(dom_info);
2437 dom_info.info12 = *info12;
2439 status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2440 domain_handle,
2442 &dom_info,
2443 &result);
2445 NT_STATUS_NOT_OK_RETURN(status);
2446 NT_STATUS_NOT_OK_RETURN(result);
2449 return NT_STATUS_OK;
2452 /****************************************************************
2453 ****************************************************************/
2455 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2456 struct rpc_pipe_client *pipe_cli,
2457 struct policy_handle *domain_handle,
2458 struct USER_MODALS_INFO_0 *info0)
2460 NTSTATUS status;
2461 struct samr_DomInfo1 dom_info_1;
2462 struct samr_DomInfo3 dom_info_3;
2464 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2465 pipe_cli,
2466 domain_handle,
2467 &dom_info_1,
2468 &dom_info_3,
2469 NULL,
2470 NULL,
2471 NULL,
2472 NULL);
2473 NT_STATUS_NOT_OK_RETURN(status);
2475 dom_info_1.min_password_length =
2476 info0->usrmod0_min_passwd_len;
2477 dom_info_1.password_history_length =
2478 info0->usrmod0_password_hist_len;
2480 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2481 info0->usrmod0_max_passwd_age);
2482 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2483 info0->usrmod0_min_passwd_age);
2485 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2486 info0->usrmod0_force_logoff);
2488 return set_USER_MODALS_INFO_rpc(mem_ctx,
2489 pipe_cli,
2490 domain_handle,
2491 &dom_info_1,
2492 &dom_info_3,
2493 NULL);
2496 /****************************************************************
2497 ****************************************************************/
2499 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2500 struct rpc_pipe_client *pipe_cli,
2501 struct policy_handle *domain_handle,
2502 struct USER_MODALS_INFO_3 *info3)
2504 NTSTATUS status;
2505 struct samr_DomInfo12 dom_info_12;
2507 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2508 pipe_cli,
2509 domain_handle,
2510 NULL,
2511 NULL,
2512 NULL,
2513 NULL,
2514 NULL,
2515 &dom_info_12);
2516 NT_STATUS_NOT_OK_RETURN(status);
2518 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2519 info3->usrmod3_lockout_duration);
2520 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2521 info3->usrmod3_lockout_observation_window);
2522 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2524 return set_USER_MODALS_INFO_rpc(mem_ctx,
2525 pipe_cli,
2526 domain_handle,
2527 NULL,
2528 NULL,
2529 &dom_info_12);
2532 /****************************************************************
2533 ****************************************************************/
2535 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2536 struct rpc_pipe_client *pipe_cli,
2537 struct policy_handle *domain_handle,
2538 struct USER_MODALS_INFO_1001 *info1001)
2540 NTSTATUS status;
2541 struct samr_DomInfo1 dom_info_1;
2543 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2544 pipe_cli,
2545 domain_handle,
2546 &dom_info_1,
2547 NULL,
2548 NULL,
2549 NULL,
2550 NULL,
2551 NULL);
2552 NT_STATUS_NOT_OK_RETURN(status);
2554 dom_info_1.min_password_length =
2555 info1001->usrmod1001_min_passwd_len;
2557 return set_USER_MODALS_INFO_rpc(mem_ctx,
2558 pipe_cli,
2559 domain_handle,
2560 &dom_info_1,
2561 NULL,
2562 NULL);
2565 /****************************************************************
2566 ****************************************************************/
2568 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2569 struct rpc_pipe_client *pipe_cli,
2570 struct policy_handle *domain_handle,
2571 struct USER_MODALS_INFO_1002 *info1002)
2573 NTSTATUS status;
2574 struct samr_DomInfo1 dom_info_1;
2576 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2577 pipe_cli,
2578 domain_handle,
2579 &dom_info_1,
2580 NULL,
2581 NULL,
2582 NULL,
2583 NULL,
2584 NULL);
2585 NT_STATUS_NOT_OK_RETURN(status);
2587 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2588 info1002->usrmod1002_max_passwd_age);
2590 return set_USER_MODALS_INFO_rpc(mem_ctx,
2591 pipe_cli,
2592 domain_handle,
2593 &dom_info_1,
2594 NULL,
2595 NULL);
2598 /****************************************************************
2599 ****************************************************************/
2601 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2602 struct rpc_pipe_client *pipe_cli,
2603 struct policy_handle *domain_handle,
2604 struct USER_MODALS_INFO_1003 *info1003)
2606 NTSTATUS status;
2607 struct samr_DomInfo1 dom_info_1;
2609 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2610 pipe_cli,
2611 domain_handle,
2612 &dom_info_1,
2613 NULL,
2614 NULL,
2615 NULL,
2616 NULL,
2617 NULL);
2618 NT_STATUS_NOT_OK_RETURN(status);
2620 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2621 info1003->usrmod1003_min_passwd_age);
2623 return set_USER_MODALS_INFO_rpc(mem_ctx,
2624 pipe_cli,
2625 domain_handle,
2626 &dom_info_1,
2627 NULL,
2628 NULL);
2631 /****************************************************************
2632 ****************************************************************/
2634 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2635 struct rpc_pipe_client *pipe_cli,
2636 struct policy_handle *domain_handle,
2637 struct USER_MODALS_INFO_1004 *info1004)
2639 NTSTATUS status;
2640 struct samr_DomInfo3 dom_info_3;
2642 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2643 pipe_cli,
2644 domain_handle,
2645 NULL,
2646 &dom_info_3,
2647 NULL,
2648 NULL,
2649 NULL,
2650 NULL);
2651 NT_STATUS_NOT_OK_RETURN(status);
2653 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2654 info1004->usrmod1004_force_logoff);
2656 return set_USER_MODALS_INFO_rpc(mem_ctx,
2657 pipe_cli,
2658 domain_handle,
2659 NULL,
2660 &dom_info_3,
2661 NULL);
2664 /****************************************************************
2665 ****************************************************************/
2667 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2668 struct rpc_pipe_client *pipe_cli,
2669 struct policy_handle *domain_handle,
2670 struct USER_MODALS_INFO_1005 *info1005)
2672 NTSTATUS status;
2673 struct samr_DomInfo1 dom_info_1;
2675 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2676 pipe_cli,
2677 domain_handle,
2678 &dom_info_1,
2679 NULL,
2680 NULL,
2681 NULL,
2682 NULL,
2683 NULL);
2684 NT_STATUS_NOT_OK_RETURN(status);
2686 dom_info_1.password_history_length =
2687 info1005->usrmod1005_password_hist_len;
2689 return set_USER_MODALS_INFO_rpc(mem_ctx,
2690 pipe_cli,
2691 domain_handle,
2692 &dom_info_1,
2693 NULL,
2694 NULL);
2697 /****************************************************************
2698 ****************************************************************/
2700 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2701 struct rpc_pipe_client *pipe_cli,
2702 uint32_t level,
2703 struct policy_handle *domain_handle,
2704 struct dom_sid *domain_sid,
2705 uint8_t *buffer)
2707 struct USER_MODALS_INFO_0 *info0;
2708 struct USER_MODALS_INFO_3 *info3;
2709 struct USER_MODALS_INFO_1001 *info1001;
2710 struct USER_MODALS_INFO_1002 *info1002;
2711 struct USER_MODALS_INFO_1003 *info1003;
2712 struct USER_MODALS_INFO_1004 *info1004;
2713 struct USER_MODALS_INFO_1005 *info1005;
2715 if (!buffer) {
2716 return ERROR_INSUFFICIENT_BUFFER;
2719 switch (level) {
2720 case 0:
2721 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2722 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2723 pipe_cli,
2724 domain_handle,
2725 info0);
2726 case 3:
2727 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2728 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2729 pipe_cli,
2730 domain_handle,
2731 info3);
2732 case 1001:
2733 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2734 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2735 pipe_cli,
2736 domain_handle,
2737 info1001);
2738 case 1002:
2739 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2740 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2741 pipe_cli,
2742 domain_handle,
2743 info1002);
2744 case 1003:
2745 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2746 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2747 pipe_cli,
2748 domain_handle,
2749 info1003);
2750 case 1004:
2751 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2752 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2753 pipe_cli,
2754 domain_handle,
2755 info1004);
2756 case 1005:
2757 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2758 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2759 pipe_cli,
2760 domain_handle,
2761 info1005);
2763 default:
2764 break;
2767 return NT_STATUS_OK;
2770 /****************************************************************
2771 ****************************************************************/
2773 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2774 struct NetUserModalsSet *r)
2776 struct rpc_pipe_client *pipe_cli = NULL;
2777 NTSTATUS status;
2778 WERROR werr;
2780 struct policy_handle connect_handle, domain_handle;
2781 struct dom_sid2 *domain_sid = NULL;
2782 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2784 ZERO_STRUCT(connect_handle);
2785 ZERO_STRUCT(domain_handle);
2787 if (!r->in.buffer) {
2788 return WERR_INVALID_PARAMETER;
2791 switch (r->in.level) {
2792 case 0:
2793 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2794 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2795 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2796 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2797 break;
2798 case 3:
2799 case 1001:
2800 case 1002:
2801 case 1003:
2802 case 1005:
2803 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2804 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2805 break;
2806 case 1004:
2807 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2808 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2809 break;
2810 case 1:
2811 case 2:
2812 case 1006:
2813 case 1007:
2814 werr = WERR_NOT_SUPPORTED;
2815 break;
2816 default:
2817 werr = WERR_INVALID_LEVEL;
2818 goto done;
2821 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2822 &ndr_table_samr,
2823 &pipe_cli);
2824 if (!W_ERROR_IS_OK(werr)) {
2825 goto done;
2828 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2829 SAMR_ACCESS_ENUM_DOMAINS |
2830 SAMR_ACCESS_LOOKUP_DOMAIN,
2831 access_mask,
2832 &connect_handle,
2833 &domain_handle,
2834 &domain_sid);
2835 if (!W_ERROR_IS_OK(werr)) {
2836 goto done;
2839 status = set_USER_MODALS_INFO_buffer(ctx,
2840 pipe_cli,
2841 r->in.level,
2842 &domain_handle,
2843 domain_sid,
2844 r->in.buffer);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 werr = ntstatus_to_werror(status);
2847 goto done;
2850 done:
2851 if (ctx->disable_policy_handle_cache) {
2852 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2853 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2856 return werr;
2859 /****************************************************************
2860 ****************************************************************/
2862 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2863 struct NetUserModalsSet *r)
2865 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2868 /****************************************************************
2869 ****************************************************************/
2871 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2872 uint32_t level,
2873 const char *group_name,
2874 uint32_t attributes,
2875 uint8_t **buffer,
2876 uint32_t *num_entries)
2878 struct GROUP_USERS_INFO_0 u0;
2879 struct GROUP_USERS_INFO_1 u1;
2881 switch (level) {
2882 case 0:
2883 if (group_name) {
2884 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2885 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2886 } else {
2887 u0.grui0_name = NULL;
2890 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2891 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2892 break;
2893 case 1:
2894 if (group_name) {
2895 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2896 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2897 } else {
2898 u1.grui1_name = NULL;
2901 u1.grui1_attributes = attributes;
2903 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2904 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2905 break;
2906 default:
2907 return NT_STATUS_INVALID_INFO_CLASS;
2910 return NT_STATUS_OK;
2913 /****************************************************************
2914 ****************************************************************/
2916 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2917 struct NetUserGetGroups *r)
2919 struct rpc_pipe_client *pipe_cli = NULL;
2920 struct policy_handle connect_handle, domain_handle, user_handle;
2921 struct lsa_String lsa_account_name;
2922 struct dom_sid2 *domain_sid = NULL;
2923 struct samr_Ids user_rids, name_types;
2924 struct samr_RidWithAttributeArray *rid_array = NULL;
2925 struct lsa_Strings names;
2926 struct samr_Ids types;
2927 uint32_t *rids = NULL;
2929 int i;
2930 uint32_t entries_read = 0;
2932 NTSTATUS status;
2933 NTSTATUS result = NT_STATUS_OK;
2934 WERROR werr;
2935 struct dcerpc_binding_handle *b = NULL;
2937 ZERO_STRUCT(connect_handle);
2938 ZERO_STRUCT(domain_handle);
2940 if (!r->out.buffer) {
2941 return WERR_INVALID_PARAMETER;
2944 *r->out.buffer = NULL;
2945 *r->out.entries_read = 0;
2946 *r->out.total_entries = 0;
2948 switch (r->in.level) {
2949 case 0:
2950 case 1:
2951 break;
2952 default:
2953 return WERR_INVALID_LEVEL;
2956 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2957 &ndr_table_samr,
2958 &pipe_cli);
2959 if (!W_ERROR_IS_OK(werr)) {
2960 goto done;
2963 b = pipe_cli->binding_handle;
2965 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2966 SAMR_ACCESS_ENUM_DOMAINS |
2967 SAMR_ACCESS_LOOKUP_DOMAIN,
2968 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2969 &connect_handle,
2970 &domain_handle,
2971 &domain_sid);
2972 if (!W_ERROR_IS_OK(werr)) {
2973 goto done;
2976 init_lsa_String(&lsa_account_name, r->in.user_name);
2978 status = dcerpc_samr_LookupNames(b, talloc_tos(),
2979 &domain_handle,
2981 &lsa_account_name,
2982 &user_rids,
2983 &name_types,
2984 &result);
2985 if (any_nt_status_not_ok(status, result, &status)) {
2986 werr = ntstatus_to_werror(status);
2987 goto done;
2989 if (user_rids.count != 1) {
2990 werr = WERR_BAD_NET_RESP;
2991 goto done;
2993 if (name_types.count != 1) {
2994 werr = WERR_BAD_NET_RESP;
2995 goto done;
2998 status = dcerpc_samr_OpenUser(b, talloc_tos(),
2999 &domain_handle,
3000 SAMR_USER_ACCESS_GET_GROUPS,
3001 user_rids.ids[0],
3002 &user_handle,
3003 &result);
3004 if (any_nt_status_not_ok(status, result, &status)) {
3005 werr = ntstatus_to_werror(status);
3006 goto done;
3009 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3010 &user_handle,
3011 &rid_array,
3012 &result);
3013 if (any_nt_status_not_ok(status, result, &status)) {
3014 werr = ntstatus_to_werror(status);
3015 goto done;
3018 rids = talloc_array(ctx, uint32_t, rid_array->count);
3019 if (!rids) {
3020 werr = WERR_NOT_ENOUGH_MEMORY;
3021 goto done;
3024 for (i=0; i < rid_array->count; i++) {
3025 rids[i] = rid_array->rids[i].rid;
3028 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3029 &domain_handle,
3030 rid_array->count,
3031 rids,
3032 &names,
3033 &types,
3034 &result);
3035 if (!NT_STATUS_IS_OK(status)) {
3036 werr = ntstatus_to_werror(status);
3037 goto done;
3039 if (!NT_STATUS_IS_OK(result) &&
3040 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3041 werr = ntstatus_to_werror(result);
3042 goto done;
3044 if (names.count != rid_array->count) {
3045 werr = WERR_BAD_NET_RESP;
3046 goto done;
3048 if (types.count != rid_array->count) {
3049 werr = WERR_BAD_NET_RESP;
3050 goto done;
3053 for (i=0; i < names.count; i++) {
3054 status = add_GROUP_USERS_INFO_X_buffer(ctx,
3055 r->in.level,
3056 names.names[i].string,
3057 rid_array->rids[i].attributes,
3058 r->out.buffer,
3059 &entries_read);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 werr = ntstatus_to_werror(status);
3062 goto done;
3066 *r->out.entries_read = entries_read;
3067 *r->out.total_entries = entries_read;
3069 done:
3070 if (ctx->disable_policy_handle_cache) {
3071 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3072 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3075 return werr;
3078 /****************************************************************
3079 ****************************************************************/
3081 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
3082 struct NetUserGetGroups *r)
3084 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
3087 /****************************************************************
3088 ****************************************************************/
3090 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
3091 struct NetUserSetGroups *r)
3093 struct rpc_pipe_client *pipe_cli = NULL;
3094 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
3095 struct lsa_String lsa_account_name;
3096 struct dom_sid2 *domain_sid = NULL;
3097 struct samr_Ids user_rids, name_types;
3098 struct samr_Ids group_rids;
3099 struct samr_RidWithAttributeArray *rid_array = NULL;
3100 struct lsa_String *lsa_names = NULL;
3102 uint32_t *add_rids = NULL;
3103 uint32_t *del_rids = NULL;
3104 size_t num_add_rids = 0;
3105 size_t num_del_rids = 0;
3107 uint32_t *member_rids = NULL;
3109 struct GROUP_USERS_INFO_0 *i0 = NULL;
3110 struct GROUP_USERS_INFO_1 *i1 = NULL;
3112 int i, k;
3114 NTSTATUS status;
3115 NTSTATUS result = NT_STATUS_OK;
3116 WERROR werr;
3117 struct dcerpc_binding_handle *b = NULL;
3119 ZERO_STRUCT(connect_handle);
3120 ZERO_STRUCT(domain_handle);
3121 ZERO_STRUCT(group_handle);
3123 if (!r->in.buffer) {
3124 return WERR_INVALID_PARAMETER;
3127 switch (r->in.level) {
3128 case 0:
3129 case 1:
3130 break;
3131 default:
3132 return WERR_INVALID_LEVEL;
3135 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3136 &ndr_table_samr,
3137 &pipe_cli);
3138 if (!W_ERROR_IS_OK(werr)) {
3139 goto done;
3142 b = pipe_cli->binding_handle;
3144 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3145 SAMR_ACCESS_ENUM_DOMAINS |
3146 SAMR_ACCESS_LOOKUP_DOMAIN,
3147 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3148 &connect_handle,
3149 &domain_handle,
3150 &domain_sid);
3151 if (!W_ERROR_IS_OK(werr)) {
3152 goto done;
3155 init_lsa_String(&lsa_account_name, r->in.user_name);
3157 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3158 &domain_handle,
3160 &lsa_account_name,
3161 &user_rids,
3162 &name_types,
3163 &result);
3164 if (any_nt_status_not_ok(status, result, &status)) {
3165 werr = ntstatus_to_werror(status);
3166 goto done;
3168 if (user_rids.count != 1) {
3169 werr = WERR_BAD_NET_RESP;
3170 goto done;
3172 if (name_types.count != 1) {
3173 werr = WERR_BAD_NET_RESP;
3174 goto done;
3177 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3178 &domain_handle,
3179 SAMR_USER_ACCESS_GET_GROUPS,
3180 user_rids.ids[0],
3181 &user_handle,
3182 &result);
3183 if (any_nt_status_not_ok(status, result, &status)) {
3184 werr = ntstatus_to_werror(status);
3185 goto done;
3188 switch (r->in.level) {
3189 case 0:
3190 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3191 break;
3192 case 1:
3193 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3194 break;
3197 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3198 if (!lsa_names) {
3199 werr = WERR_NOT_ENOUGH_MEMORY;
3200 goto done;
3203 for (i=0; i < r->in.num_entries; i++) {
3205 switch (r->in.level) {
3206 case 0:
3207 init_lsa_String(&lsa_names[i], i0->grui0_name);
3208 i0++;
3209 break;
3210 case 1:
3211 init_lsa_String(&lsa_names[i], i1->grui1_name);
3212 i1++;
3213 break;
3217 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3218 &domain_handle,
3219 r->in.num_entries,
3220 lsa_names,
3221 &group_rids,
3222 &name_types,
3223 &result);
3224 if (any_nt_status_not_ok(status, result, &status)) {
3225 werr = ntstatus_to_werror(status);
3226 goto done;
3228 if (group_rids.count != r->in.num_entries) {
3229 werr = WERR_BAD_NET_RESP;
3230 goto done;
3232 if (name_types.count != r->in.num_entries) {
3233 werr = WERR_BAD_NET_RESP;
3234 goto done;
3237 member_rids = group_rids.ids;
3239 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3240 &user_handle,
3241 &rid_array,
3242 &result);
3243 if (any_nt_status_not_ok(status, result, &status)) {
3244 werr = ntstatus_to_werror(status);
3245 goto done;
3248 /* add list */
3250 for (i=0; i < r->in.num_entries; i++) {
3251 bool already_member = false;
3252 for (k=0; k < rid_array->count; k++) {
3253 if (member_rids[i] == rid_array->rids[k].rid) {
3254 already_member = true;
3255 break;
3258 if (!already_member) {
3259 if (!add_rid_to_array_unique(ctx,
3260 member_rids[i],
3261 &add_rids, &num_add_rids)) {
3262 werr = WERR_GEN_FAILURE;
3263 goto done;
3268 /* del list */
3270 for (k=0; k < rid_array->count; k++) {
3271 bool keep_member = false;
3272 for (i=0; i < r->in.num_entries; i++) {
3273 if (member_rids[i] == rid_array->rids[k].rid) {
3274 keep_member = true;
3275 break;
3278 if (!keep_member) {
3279 if (!add_rid_to_array_unique(ctx,
3280 rid_array->rids[k].rid,
3281 &del_rids, &num_del_rids)) {
3282 werr = WERR_GEN_FAILURE;
3283 goto done;
3288 /* add list */
3290 for (i=0; i < num_add_rids; i++) {
3291 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3292 &domain_handle,
3293 SAMR_GROUP_ACCESS_ADD_MEMBER,
3294 add_rids[i],
3295 &group_handle,
3296 &result);
3297 if (any_nt_status_not_ok(status, result, &status)) {
3298 werr = ntstatus_to_werror(status);
3299 goto done;
3302 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
3303 &group_handle,
3304 user_rids.ids[0],
3305 7 /* ? */,
3306 &result);
3307 if (any_nt_status_not_ok(status, result, &status)) {
3308 werr = ntstatus_to_werror(status);
3309 goto done;
3312 if (is_valid_policy_hnd(&group_handle)) {
3313 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3317 /* del list */
3319 for (i=0; i < num_del_rids; i++) {
3320 status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3321 &domain_handle,
3322 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3323 del_rids[i],
3324 &group_handle,
3325 &result);
3326 if (any_nt_status_not_ok(status, result, &status)) {
3327 werr = ntstatus_to_werror(status);
3328 goto done;
3331 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
3332 &group_handle,
3333 user_rids.ids[0],
3334 &result);
3335 if (any_nt_status_not_ok(status, result, &status)) {
3336 werr = ntstatus_to_werror(status);
3337 goto done;
3340 if (is_valid_policy_hnd(&group_handle)) {
3341 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3345 werr = WERR_OK;
3347 done:
3348 if (is_valid_policy_hnd(&group_handle)) {
3349 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3352 if (ctx->disable_policy_handle_cache) {
3353 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3354 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3357 return werr;
3360 /****************************************************************
3361 ****************************************************************/
3363 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3364 struct NetUserSetGroups *r)
3366 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3369 /****************************************************************
3370 ****************************************************************/
3372 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3373 uint32_t level,
3374 const char *group_name,
3375 uint8_t **buffer,
3376 uint32_t *num_entries)
3378 struct LOCALGROUP_USERS_INFO_0 u0;
3380 switch (level) {
3381 case 0:
3382 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3383 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3385 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3386 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3387 break;
3388 default:
3389 return NT_STATUS_INVALID_INFO_CLASS;
3392 return NT_STATUS_OK;
3395 /****************************************************************
3396 ****************************************************************/
3398 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3399 struct NetUserGetLocalGroups *r)
3401 struct rpc_pipe_client *pipe_cli = NULL;
3402 struct policy_handle connect_handle, domain_handle, user_handle,
3403 builtin_handle;
3404 struct lsa_String lsa_account_name;
3405 struct dom_sid2 *domain_sid = NULL;
3406 struct samr_Ids user_rids, name_types;
3407 struct samr_RidWithAttributeArray *rid_array = NULL;
3408 struct lsa_Strings names;
3409 struct samr_Ids types;
3410 uint32_t *rids = NULL;
3411 size_t num_rids = 0;
3412 struct dom_sid user_sid;
3413 struct lsa_SidArray sid_array;
3414 struct samr_Ids domain_rids;
3415 struct samr_Ids builtin_rids;
3417 int i;
3418 uint32_t entries_read = 0;
3420 NTSTATUS status;
3421 NTSTATUS result = NT_STATUS_OK;
3422 WERROR werr;
3423 struct dcerpc_binding_handle *b = NULL;
3425 ZERO_STRUCT(connect_handle);
3426 ZERO_STRUCT(domain_handle);
3428 if (!r->out.buffer) {
3429 return WERR_INVALID_PARAMETER;
3432 *r->out.buffer = NULL;
3433 *r->out.entries_read = 0;
3434 *r->out.total_entries = 0;
3436 switch (r->in.level) {
3437 case 0:
3438 case 1:
3439 break;
3440 default:
3441 return WERR_INVALID_LEVEL;
3444 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3445 &ndr_table_samr,
3446 &pipe_cli);
3447 if (!W_ERROR_IS_OK(werr)) {
3448 goto done;
3451 b = pipe_cli->binding_handle;
3453 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3454 SAMR_ACCESS_ENUM_DOMAINS |
3455 SAMR_ACCESS_LOOKUP_DOMAIN,
3456 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3457 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3458 &connect_handle,
3459 &domain_handle,
3460 &domain_sid);
3461 if (!W_ERROR_IS_OK(werr)) {
3462 goto done;
3465 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3466 SAMR_ACCESS_ENUM_DOMAINS |
3467 SAMR_ACCESS_LOOKUP_DOMAIN,
3468 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3469 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3470 &connect_handle,
3471 &builtin_handle);
3472 if (!W_ERROR_IS_OK(werr)) {
3473 goto done;
3476 init_lsa_String(&lsa_account_name, r->in.user_name);
3478 status = dcerpc_samr_LookupNames(b, talloc_tos(),
3479 &domain_handle,
3481 &lsa_account_name,
3482 &user_rids,
3483 &name_types,
3484 &result);
3485 if (any_nt_status_not_ok(status, result, &status)) {
3486 werr = ntstatus_to_werror(status);
3487 goto done;
3489 if (user_rids.count != 1) {
3490 werr = WERR_BAD_NET_RESP;
3491 goto done;
3493 if (name_types.count != 1) {
3494 werr = WERR_BAD_NET_RESP;
3495 goto done;
3498 status = dcerpc_samr_OpenUser(b, talloc_tos(),
3499 &domain_handle,
3500 SAMR_USER_ACCESS_GET_GROUPS,
3501 user_rids.ids[0],
3502 &user_handle,
3503 &result);
3504 if (any_nt_status_not_ok(status, result, &status)) {
3505 werr = ntstatus_to_werror(status);
3506 goto done;
3509 status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3510 &user_handle,
3511 &rid_array,
3512 &result);
3513 if (any_nt_status_not_ok(status, result, &status)) {
3514 werr = ntstatus_to_werror(status);
3515 goto done;
3518 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3519 werr = WERR_NOT_ENOUGH_MEMORY;
3520 goto done;
3523 sid_array.num_sids = rid_array->count + 1;
3524 sid_array.sids = talloc_array(ctx, struct lsa_SidPtr, sid_array.num_sids);
3525 if (!sid_array.sids) {
3526 werr = WERR_NOT_ENOUGH_MEMORY;
3527 goto done;
3530 sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid);
3531 if (!sid_array.sids[0].sid) {
3532 werr = WERR_NOT_ENOUGH_MEMORY;
3533 goto done;
3536 for (i=0; i < rid_array->count; i++) {
3537 struct dom_sid sid;
3539 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3540 werr = WERR_NOT_ENOUGH_MEMORY;
3541 goto done;
3544 sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid);
3545 if (!sid_array.sids[i+1].sid) {
3546 werr = WERR_NOT_ENOUGH_MEMORY;
3547 goto done;
3551 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3552 &domain_handle,
3553 &sid_array,
3554 &domain_rids,
3555 &result);
3556 if (any_nt_status_not_ok(status, result, &status)) {
3557 werr = ntstatus_to_werror(status);
3558 goto done;
3561 for (i=0; i < domain_rids.count; i++) {
3562 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3563 &rids, &num_rids)) {
3564 werr = WERR_NOT_ENOUGH_MEMORY;
3565 goto done;
3569 status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3570 &builtin_handle,
3571 &sid_array,
3572 &builtin_rids,
3573 &result);
3574 if (any_nt_status_not_ok(status, result, &status)) {
3575 werr = ntstatus_to_werror(status);
3576 goto done;
3579 for (i=0; i < builtin_rids.count; i++) {
3580 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3581 &rids, &num_rids)) {
3582 werr = WERR_NOT_ENOUGH_MEMORY;
3583 goto done;
3587 status = dcerpc_samr_LookupRids(b, talloc_tos(),
3588 &builtin_handle,
3589 num_rids,
3590 rids,
3591 &names,
3592 &types,
3593 &result);
3594 if (any_nt_status_not_ok(status, result, &status)) {
3595 werr = ntstatus_to_werror(status);
3596 goto done;
3598 if (names.count != num_rids) {
3599 werr = WERR_BAD_NET_RESP;
3600 goto done;
3602 if (types.count != num_rids) {
3603 werr = WERR_BAD_NET_RESP;
3604 goto done;
3607 for (i=0; i < names.count; i++) {
3608 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3609 r->in.level,
3610 names.names[i].string,
3611 r->out.buffer,
3612 &entries_read);
3613 if (!NT_STATUS_IS_OK(status)) {
3614 werr = ntstatus_to_werror(status);
3615 goto done;
3619 *r->out.entries_read = entries_read;
3620 *r->out.total_entries = entries_read;
3622 done:
3623 if (ctx->disable_policy_handle_cache) {
3624 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3625 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3628 return werr;
3631 /****************************************************************
3632 ****************************************************************/
3634 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3635 struct NetUserGetLocalGroups *r)
3637 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);