source: vendor/3.5.0/source3/lib/netapi/user.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 88.8 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * NetApi User Support
4 * Copyright (C) Guenther Deschner 2008
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include "includes.h"
21
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/cli_samr.h"
27
28/****************************************************************
29****************************************************************/
30
31static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
32 struct samr_UserInfo21 *info21)
33{
34 uint32_t fields_present = 0;
35 struct samr_LogonHours zero_logon_hours;
36 struct lsa_BinaryString zero_parameters;
37 NTTIME password_age;
38
39 ZERO_STRUCTP(info21);
40 ZERO_STRUCT(zero_logon_hours);
41 ZERO_STRUCT(zero_parameters);
42
43 if (infoX->usriX_flags) {
44 fields_present |= SAMR_FIELD_ACCT_FLAGS;
45 }
46 if (infoX->usriX_name) {
47 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
48 }
49 if (infoX->usriX_password) {
50 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
51 }
52 if (infoX->usriX_flags) {
53 fields_present |= SAMR_FIELD_ACCT_FLAGS;
54 }
55 if (infoX->usriX_name) {
56 fields_present |= SAMR_FIELD_FULL_NAME;
57 }
58 if (infoX->usriX_home_dir) {
59 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
60 }
61 if (infoX->usriX_script_path) {
62 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
63 }
64 if (infoX->usriX_comment) {
65 fields_present |= SAMR_FIELD_DESCRIPTION;
66 }
67 if (infoX->usriX_password_age) {
68 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
69 }
70 if (infoX->usriX_full_name) {
71 fields_present |= SAMR_FIELD_FULL_NAME;
72 }
73 if (infoX->usriX_usr_comment) {
74 fields_present |= SAMR_FIELD_COMMENT;
75 }
76 if (infoX->usriX_profile) {
77 fields_present |= SAMR_FIELD_PROFILE_PATH;
78 }
79 if (infoX->usriX_home_dir_drive) {
80 fields_present |= SAMR_FIELD_HOME_DRIVE;
81 }
82 if (infoX->usriX_primary_group_id) {
83 fields_present |= SAMR_FIELD_PRIMARY_GID;
84 }
85 if (infoX->usriX_country_code) {
86 fields_present |= SAMR_FIELD_COUNTRY_CODE;
87 }
88 if (infoX->usriX_workstations) {
89 fields_present |= SAMR_FIELD_WORKSTATIONS;
90 }
91
92 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
93
94 /* TODO: infoX->usriX_priv */
95
96 info21->last_logon = 0;
97 info21->last_logoff = 0;
98 info21->last_password_change = 0;
99 info21->acct_expiry = 0;
100 info21->allow_password_change = 0;
101 info21->force_password_change = 0;
102 info21->account_name.string = infoX->usriX_name;
103 info21->full_name.string = infoX->usriX_full_name;
104 info21->home_directory.string = infoX->usriX_home_dir;
105 info21->home_drive.string = infoX->usriX_home_dir_drive;
106 info21->logon_script.string = infoX->usriX_script_path;
107 info21->profile_path.string = infoX->usriX_profile;
108 info21->description.string = infoX->usriX_comment;
109 info21->workstations.string = infoX->usriX_workstations;
110 info21->comment.string = infoX->usriX_usr_comment;
111 info21->parameters = zero_parameters;
112 info21->lm_owf_password = zero_parameters;
113 info21->nt_owf_password = zero_parameters;
114 info21->unknown3.string = NULL;
115 info21->buf_count = 0;
116 info21->buffer = NULL;
117 info21->rid = infoX->usriX_user_id;
118 info21->primary_gid = infoX->usriX_primary_group_id;
119 info21->acct_flags = infoX->usriX_flags;
120 info21->fields_present = fields_present;
121 info21->logon_hours = zero_logon_hours;
122 info21->bad_password_count = infoX->usriX_bad_pw_count;
123 info21->logon_count = infoX->usriX_num_logons;
124 info21->country_code = infoX->usriX_country_code;
125 info21->code_page = infoX->usriX_code_page;
126 info21->lm_password_set = 0;
127 info21->nt_password_set = 0;
128 info21->password_expired = infoX->usriX_password_expired;
129 info21->unknown4 = 0;
130}
131
132/****************************************************************
133****************************************************************/
134
135static NTSTATUS construct_USER_INFO_X(uint32_t level,
136 uint8_t *buffer,
137 struct USER_INFO_X *uX)
138{
139 struct USER_INFO_0 *u0 = NULL;
140 struct USER_INFO_1 *u1 = NULL;
141 struct USER_INFO_2 *u2 = NULL;
142 struct USER_INFO_3 *u3 = NULL;
143 struct USER_INFO_1003 *u1003 = NULL;
144 struct USER_INFO_1006 *u1006 = NULL;
145 struct USER_INFO_1007 *u1007 = NULL;
146 struct USER_INFO_1009 *u1009 = NULL;
147 struct USER_INFO_1011 *u1011 = NULL;
148 struct USER_INFO_1012 *u1012 = NULL;
149 struct USER_INFO_1014 *u1014 = NULL;
150 struct USER_INFO_1024 *u1024 = NULL;
151 struct USER_INFO_1051 *u1051 = NULL;
152 struct USER_INFO_1052 *u1052 = NULL;
153 struct USER_INFO_1053 *u1053 = NULL;
154
155 if (!buffer || !uX) {
156 return NT_STATUS_INVALID_PARAMETER;
157 }
158
159 ZERO_STRUCTP(uX);
160
161 switch (level) {
162 case 0:
163 u0 = (struct USER_INFO_0 *)buffer;
164 uX->usriX_name = u0->usri0_name;
165 break;
166 case 1:
167 u1 = (struct USER_INFO_1 *)buffer;
168 uX->usriX_name = u1->usri1_name;
169 uX->usriX_password = u1->usri1_password;
170 uX->usriX_password_age = u1->usri1_password_age;
171 uX->usriX_priv = u1->usri1_priv;
172 uX->usriX_home_dir = u1->usri1_home_dir;
173 uX->usriX_comment = u1->usri1_comment;
174 uX->usriX_flags = u1->usri1_flags;
175 uX->usriX_script_path = u1->usri1_script_path;
176 break;
177 case 2:
178 u2 = (struct USER_INFO_2 *)buffer;
179 uX->usriX_name = u2->usri2_name;
180 uX->usriX_password = u2->usri2_password;
181 uX->usriX_password_age = u2->usri2_password_age;
182 uX->usriX_priv = u2->usri2_priv;
183 uX->usriX_home_dir = u2->usri2_home_dir;
184 uX->usriX_comment = u2->usri2_comment;
185 uX->usriX_flags = u2->usri2_flags;
186 uX->usriX_script_path = u2->usri2_script_path;
187 uX->usriX_auth_flags = u2->usri2_auth_flags;
188 uX->usriX_full_name = u2->usri2_full_name;
189 uX->usriX_usr_comment = u2->usri2_usr_comment;
190 uX->usriX_parms = u2->usri2_parms;
191 uX->usriX_workstations = u2->usri2_workstations;
192 uX->usriX_last_logon = u2->usri2_last_logon;
193 uX->usriX_last_logoff = u2->usri2_last_logoff;
194 uX->usriX_acct_expires = u2->usri2_acct_expires;
195 uX->usriX_max_storage = u2->usri2_max_storage;
196 uX->usriX_units_per_week= u2->usri2_units_per_week;
197 uX->usriX_logon_hours = u2->usri2_logon_hours;
198 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
199 uX->usriX_num_logons = u2->usri2_num_logons;
200 uX->usriX_logon_server = u2->usri2_logon_server;
201 uX->usriX_country_code = u2->usri2_country_code;
202 uX->usriX_code_page = u2->usri2_code_page;
203 break;
204 case 3:
205 u3 = (struct USER_INFO_3 *)buffer;
206 uX->usriX_name = u3->usri3_name;
207 uX->usriX_password_age = u3->usri3_password_age;
208 uX->usriX_priv = u3->usri3_priv;
209 uX->usriX_home_dir = u3->usri3_home_dir;
210 uX->usriX_comment = u3->usri3_comment;
211 uX->usriX_flags = u3->usri3_flags;
212 uX->usriX_script_path = u3->usri3_script_path;
213 uX->usriX_auth_flags = u3->usri3_auth_flags;
214 uX->usriX_full_name = u3->usri3_full_name;
215 uX->usriX_usr_comment = u3->usri3_usr_comment;
216 uX->usriX_parms = u3->usri3_parms;
217 uX->usriX_workstations = u3->usri3_workstations;
218 uX->usriX_last_logon = u3->usri3_last_logon;
219 uX->usriX_last_logoff = u3->usri3_last_logoff;
220 uX->usriX_acct_expires = u3->usri3_acct_expires;
221 uX->usriX_max_storage = u3->usri3_max_storage;
222 uX->usriX_units_per_week= u3->usri3_units_per_week;
223 uX->usriX_logon_hours = u3->usri3_logon_hours;
224 uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
225 uX->usriX_num_logons = u3->usri3_num_logons;
226 uX->usriX_logon_server = u3->usri3_logon_server;
227 uX->usriX_country_code = u3->usri3_country_code;
228 uX->usriX_code_page = u3->usri3_code_page;
229 uX->usriX_user_id = u3->usri3_user_id;
230 uX->usriX_primary_group_id = u3->usri3_primary_group_id;
231 uX->usriX_profile = u3->usri3_profile;
232 uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
233 uX->usriX_password_expired = u3->usri3_password_expired;
234 break;
235 case 1003:
236 u1003 = (struct USER_INFO_1003 *)buffer;
237 uX->usriX_password = u1003->usri1003_password;
238 break;
239 case 1006:
240 u1006 = (struct USER_INFO_1006 *)buffer;
241 uX->usriX_home_dir = u1006->usri1006_home_dir;
242 break;
243 case 1007:
244 u1007 = (struct USER_INFO_1007 *)buffer;
245 uX->usriX_comment = u1007->usri1007_comment;
246 break;
247 case 1009:
248 u1009 = (struct USER_INFO_1009 *)buffer;
249 uX->usriX_script_path = u1009->usri1009_script_path;
250 break;
251 case 1011:
252 u1011 = (struct USER_INFO_1011 *)buffer;
253 uX->usriX_full_name = u1011->usri1011_full_name;
254 break;
255 case 1012:
256 u1012 = (struct USER_INFO_1012 *)buffer;
257 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
258 break;
259 case 1014:
260 u1014 = (struct USER_INFO_1014 *)buffer;
261 uX->usriX_workstations = u1014->usri1014_workstations;
262 break;
263 case 1024:
264 u1024 = (struct USER_INFO_1024 *)buffer;
265 uX->usriX_country_code = u1024->usri1024_country_code;
266 break;
267 case 1051:
268 u1051 = (struct USER_INFO_1051 *)buffer;
269 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
270 break;
271 case 1052:
272 u1052 = (struct USER_INFO_1052 *)buffer;
273 uX->usriX_profile = u1052->usri1052_profile;
274 break;
275 case 1053:
276 u1053 = (struct USER_INFO_1053 *)buffer;
277 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
278 break;
279 case 4:
280 default:
281 return NT_STATUS_INVALID_INFO_CLASS;
282 }
283
284 return NT_STATUS_OK;
285}
286
287/****************************************************************
288****************************************************************/
289
290static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
291 struct rpc_pipe_client *pipe_cli,
292 DATA_BLOB *session_key,
293 struct policy_handle *user_handle,
294 struct USER_INFO_X *uX)
295{
296 union samr_UserInfo user_info;
297 struct samr_UserInfo21 info21;
298 NTSTATUS status;
299
300 if (!uX) {
301 return NT_STATUS_INVALID_PARAMETER;
302 }
303
304 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
305
306 ZERO_STRUCT(user_info);
307
308 if (uX->usriX_password) {
309
310 user_info.info25.info = info21;
311
312 init_samr_CryptPasswordEx(uX->usriX_password,
313 session_key,
314 &user_info.info25.password);
315
316 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
317 user_handle,
318 25,
319 &user_info);
320
321 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
322
323 user_info.info23.info = info21;
324
325 init_samr_CryptPassword(uX->usriX_password,
326 session_key,
327 &user_info.info23.password);
328
329 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
330 user_handle,
331 23,
332 &user_info);
333 }
334 } else {
335
336 user_info.info21 = info21;
337
338 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
339 user_handle,
340 21,
341 &user_info);
342 }
343
344 return status;
345}
346
347/****************************************************************
348****************************************************************/
349
350WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
351 struct NetUserAdd *r)
352{
353 struct rpc_pipe_client *pipe_cli = NULL;
354 NTSTATUS status;
355 WERROR werr;
356 struct policy_handle connect_handle, domain_handle, user_handle;
357 struct lsa_String lsa_account_name;
358 struct dom_sid2 *domain_sid = NULL;
359 union samr_UserInfo *user_info = NULL;
360 struct samr_PwInfo pw_info;
361 uint32_t access_granted = 0;
362 uint32_t rid = 0;
363 struct USER_INFO_X uX;
364
365 ZERO_STRUCT(connect_handle);
366 ZERO_STRUCT(domain_handle);
367 ZERO_STRUCT(user_handle);
368
369 if (!r->in.buffer) {
370 return WERR_INVALID_PARAM;
371 }
372
373 switch (r->in.level) {
374 case 1:
375 break;
376 case 2:
377 case 3:
378 case 4:
379 default:
380 werr = WERR_NOT_SUPPORTED;
381 goto done;
382 }
383
384 werr = libnetapi_open_pipe(ctx, r->in.server_name,
385 &ndr_table_samr.syntax_id,
386 &pipe_cli);
387 if (!W_ERROR_IS_OK(werr)) {
388 goto done;
389 }
390
391 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
392 if (!NT_STATUS_IS_OK(status)) {
393 werr = ntstatus_to_werror(status);
394 goto done;
395 }
396
397 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
398 SAMR_ACCESS_ENUM_DOMAINS |
399 SAMR_ACCESS_LOOKUP_DOMAIN,
400 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
401 SAMR_DOMAIN_ACCESS_CREATE_USER |
402 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
403 &connect_handle,
404 &domain_handle,
405 &domain_sid);
406 if (!W_ERROR_IS_OK(werr)) {
407 goto done;
408 }
409
410 init_lsa_String(&lsa_account_name, uX.usriX_name);
411
412 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
413 &domain_handle,
414 &lsa_account_name,
415 ACB_NORMAL,
416 SEC_STD_WRITE_DAC |
417 SEC_STD_DELETE |
418 SAMR_USER_ACCESS_SET_PASSWORD |
419 SAMR_USER_ACCESS_SET_ATTRIBUTES |
420 SAMR_USER_ACCESS_GET_ATTRIBUTES,
421 &user_handle,
422 &access_granted,
423 &rid);
424 if (!NT_STATUS_IS_OK(status)) {
425 werr = ntstatus_to_werror(status);
426 goto done;
427 }
428
429 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
430 &user_handle,
431 16,
432 &user_info);
433 if (!NT_STATUS_IS_OK(status)) {
434 werr = ntstatus_to_werror(status);
435 goto done;
436 }
437
438 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
439 werr = WERR_INVALID_PARAM;
440 goto done;
441 }
442
443 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
444 &user_handle,
445 &pw_info);
446 if (!NT_STATUS_IS_OK(status)) {
447 werr = ntstatus_to_werror(status);
448 goto done;
449 }
450
451 uX.usriX_flags |= ACB_NORMAL;
452
453 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
454 &pipe_cli->auth->user_session_key,
455 &user_handle,
456 &uX);
457 if (!NT_STATUS_IS_OK(status)) {
458 werr = ntstatus_to_werror(status);
459 goto failed;
460 }
461
462 werr = WERR_OK;
463 goto done;
464
465 failed:
466 rpccli_samr_DeleteUser(pipe_cli, ctx,
467 &user_handle);
468
469 done:
470 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
471 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
472 }
473
474 if (ctx->disable_policy_handle_cache) {
475 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
476 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
477 }
478
479 return werr;
480}
481
482/****************************************************************
483****************************************************************/
484
485WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
486 struct NetUserAdd *r)
487{
488 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
489}
490
491/****************************************************************
492****************************************************************/
493
494WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
495 struct NetUserDel *r)
496{
497 struct rpc_pipe_client *pipe_cli = NULL;
498 NTSTATUS status;
499 WERROR werr;
500 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
501 struct lsa_String lsa_account_name;
502 struct samr_Ids user_rids, name_types;
503 struct dom_sid2 *domain_sid = NULL;
504 struct dom_sid2 user_sid;
505
506 ZERO_STRUCT(connect_handle);
507 ZERO_STRUCT(builtin_handle);
508 ZERO_STRUCT(domain_handle);
509 ZERO_STRUCT(user_handle);
510
511 werr = libnetapi_open_pipe(ctx, r->in.server_name,
512 &ndr_table_samr.syntax_id,
513 &pipe_cli);
514
515 if (!W_ERROR_IS_OK(werr)) {
516 goto done;
517 }
518
519 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
520 SAMR_ACCESS_ENUM_DOMAINS |
521 SAMR_ACCESS_LOOKUP_DOMAIN,
522 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
523 &connect_handle,
524 &domain_handle,
525 &domain_sid);
526 if (!W_ERROR_IS_OK(werr)) {
527 goto done;
528 }
529
530 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
531 &connect_handle,
532 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
533 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
534 &builtin_handle);
535 if (!NT_STATUS_IS_OK(status)) {
536 werr = ntstatus_to_werror(status);
537 goto done;
538 }
539
540 init_lsa_String(&lsa_account_name, r->in.user_name);
541
542 status = rpccli_samr_LookupNames(pipe_cli, ctx,
543 &domain_handle,
544 1,
545 &lsa_account_name,
546 &user_rids,
547 &name_types);
548 if (!NT_STATUS_IS_OK(status)) {
549 werr = ntstatus_to_werror(status);
550 goto done;
551 }
552
553 status = rpccli_samr_OpenUser(pipe_cli, ctx,
554 &domain_handle,
555 SEC_STD_DELETE,
556 user_rids.ids[0],
557 &user_handle);
558 if (!NT_STATUS_IS_OK(status)) {
559 werr = ntstatus_to_werror(status);
560 goto done;
561 }
562
563 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
564
565 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
566 &builtin_handle,
567 &user_sid);
568 if (!NT_STATUS_IS_OK(status)) {
569 werr = ntstatus_to_werror(status);
570 goto done;
571 }
572
573 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
574 &user_handle);
575 if (!NT_STATUS_IS_OK(status)) {
576 werr = ntstatus_to_werror(status);
577 goto done;
578 }
579
580 werr = WERR_OK;
581
582 done:
583 if (is_valid_policy_hnd(&user_handle)) {
584 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
585 }
586
587 if (ctx->disable_policy_handle_cache) {
588 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
589 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
590 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
591 }
592
593 return werr;
594}
595
596/****************************************************************
597****************************************************************/
598
599WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
600 struct NetUserDel *r)
601{
602 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
603}
604
605/****************************************************************
606****************************************************************/
607
608static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
609 struct rpc_pipe_client *pipe_cli,
610 struct policy_handle *domain_handle,
611 struct policy_handle *builtin_handle,
612 const char *user_name,
613 const struct dom_sid *domain_sid,
614 uint32_t rid,
615 uint32_t level,
616 struct samr_UserInfo21 **info21,
617 struct sec_desc_buf **sec_desc,
618 uint32_t *auth_flag_p)
619{
620 NTSTATUS status;
621
622 struct policy_handle user_handle;
623 union samr_UserInfo *user_info = NULL;
624 struct samr_RidWithAttributeArray *rid_array = NULL;
625 uint32_t access_mask = SEC_STD_READ_CONTROL |
626 SAMR_USER_ACCESS_GET_ATTRIBUTES |
627 SAMR_USER_ACCESS_GET_NAME_ETC;
628
629 ZERO_STRUCT(user_handle);
630
631 switch (level) {
632 case 0:
633 break;
634 case 1:
635 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
636 SAMR_USER_ACCESS_GET_GROUPS;
637 break;
638 case 2:
639 case 3:
640 case 4:
641 case 11:
642 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
643 SAMR_USER_ACCESS_GET_GROUPS |
644 SAMR_USER_ACCESS_GET_LOCALE;
645 break;
646 case 10:
647 case 20:
648 case 23:
649 break;
650 default:
651 return NT_STATUS_INVALID_LEVEL;
652 }
653
654 if (level == 0) {
655 return NT_STATUS_OK;
656 }
657
658 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
659 domain_handle,
660 access_mask,
661 rid,
662 &user_handle);
663 if (!NT_STATUS_IS_OK(status)) {
664 goto done;
665 }
666
667 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
668 &user_handle,
669 21,
670 &user_info);
671 if (!NT_STATUS_IS_OK(status)) {
672 goto done;
673 }
674
675 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
676 &user_handle,
677 SECINFO_DACL,
678 sec_desc);
679 if (!NT_STATUS_IS_OK(status)) {
680 goto done;
681 }
682
683 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
684
685 struct lsa_SidArray sid_array;
686 struct samr_Ids alias_rids;
687 int i;
688 uint32_t auth_flag = 0;
689 struct dom_sid sid;
690
691 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
692 &user_handle,
693 &rid_array);
694 if (!NT_STATUS_IS_OK(status)) {
695 goto done;
696 }
697
698 sid_array.num_sids = rid_array->count + 1;
699 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
700 sid_array.num_sids);
701 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
702
703 for (i=0; i<rid_array->count; i++) {
704 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
705 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
706 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
707 }
708
709 sid_compose(&sid, domain_sid, rid);
710 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
711 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
712
713 status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
714 builtin_handle,
715 &sid_array,
716 &alias_rids);
717 if (!NT_STATUS_IS_OK(status)) {
718 goto done;
719 }
720
721 for (i=0; i<alias_rids.count; i++) {
722 switch (alias_rids.ids[i]) {
723 case 550: /* Print Operators */
724 auth_flag |= AF_OP_PRINT;
725 break;
726 case 549: /* Server Operators */
727 auth_flag |= AF_OP_SERVER;
728 break;
729 case 548: /* Account Operators */
730 auth_flag |= AF_OP_ACCOUNTS;
731 break;
732 default:
733 break;
734 }
735 }
736
737 if (auth_flag_p) {
738 *auth_flag_p = auth_flag;
739 }
740 }
741
742 *info21 = &user_info->info21;
743
744 done:
745 if (is_valid_policy_hnd(&user_handle)) {
746 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
747 }
748
749 return status;
750}
751
752/****************************************************************
753****************************************************************/
754
755static uint32_t samr_rid_to_priv_level(uint32_t rid)
756{
757 switch (rid) {
758 case DOMAIN_RID_ADMINISTRATOR:
759 return USER_PRIV_ADMIN;
760 case DOMAIN_RID_GUEST:
761 return USER_PRIV_GUEST;
762 default:
763 return USER_PRIV_USER;
764 }
765}
766
767/****************************************************************
768****************************************************************/
769
770static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
771{
772 uint32_t fl = UF_SCRIPT; /* god knows why */
773
774 fl |= ds_acb2uf(acb);
775
776 return fl;
777}
778
779/****************************************************************
780****************************************************************/
781
782static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
783 const struct samr_UserInfo21 *i21,
784 struct USER_INFO_1 *i)
785{
786 ZERO_STRUCTP(i);
787 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
788 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
789 i->usri1_password = NULL;
790 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
791 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
792 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
793 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
794 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
795 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
796
797 return NT_STATUS_OK;
798}
799
800/****************************************************************
801****************************************************************/
802
803static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
804 const struct samr_UserInfo21 *i21,
805 uint32_t auth_flag,
806 struct USER_INFO_2 *i)
807{
808 ZERO_STRUCTP(i);
809
810 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
811 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
812 i->usri2_password = NULL;
813 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
814 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
815 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
816 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
817 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
818 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
819 i->usri2_auth_flags = auth_flag;
820 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
821 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
822 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
823 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
824 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
825 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
826 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
827 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
828 i->usri2_units_per_week = i21->logon_hours.units_per_week;
829 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
830 i->usri2_bad_pw_count = i21->bad_password_count;
831 i->usri2_num_logons = i21->logon_count;
832 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
833 i->usri2_country_code = i21->country_code;
834 i->usri2_code_page = i21->code_page;
835
836 return NT_STATUS_OK;
837}
838
839/****************************************************************
840****************************************************************/
841
842static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
843 const struct samr_UserInfo21 *i21,
844 uint32_t auth_flag,
845 struct USER_INFO_3 *i)
846{
847 ZERO_STRUCTP(i);
848
849 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
850 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
851 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
852 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
853 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
854 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
855 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
856 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
857 i->usri3_auth_flags = auth_flag;
858 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
859 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
860 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
861 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
862 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
863 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
864 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
865 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
866 i->usri3_units_per_week = i21->logon_hours.units_per_week;
867 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
868 i->usri3_bad_pw_count = i21->bad_password_count;
869 i->usri3_num_logons = i21->logon_count;
870 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
871 i->usri3_country_code = i21->country_code;
872 i->usri3_code_page = i21->code_page;
873 i->usri3_user_id = i21->rid;
874 i->usri3_primary_group_id = i21->primary_gid;
875 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
876 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
877 i->usri3_password_expired = i21->password_expired;
878
879 return NT_STATUS_OK;
880}
881
882/****************************************************************
883****************************************************************/
884
885static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
886 const struct samr_UserInfo21 *i21,
887 uint32_t auth_flag,
888 struct dom_sid *domain_sid,
889 struct USER_INFO_4 *i)
890{
891 struct dom_sid sid;
892
893 ZERO_STRUCTP(i);
894
895 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
896 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
897 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
898 i->usri4_password = NULL;
899 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
900 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
901 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
902 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
903 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
904 i->usri4_auth_flags = auth_flag;
905 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
906 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
907 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
908 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
909 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
910 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
911 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
912 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
913 i->usri4_units_per_week = i21->logon_hours.units_per_week;
914 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
915 i->usri4_bad_pw_count = i21->bad_password_count;
916 i->usri4_num_logons = i21->logon_count;
917 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
918 i->usri4_country_code = i21->country_code;
919 i->usri4_code_page = i21->code_page;
920 if (!sid_compose(&sid, domain_sid, i21->rid)) {
921 return NT_STATUS_NO_MEMORY;
922 }
923 i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
924 i->usri4_primary_group_id = i21->primary_gid;
925 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
926 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
927 i->usri4_password_expired = i21->password_expired;
928
929 return NT_STATUS_OK;
930}
931
932/****************************************************************
933****************************************************************/
934
935static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
936 const struct samr_UserInfo21 *i21,
937 struct USER_INFO_10 *i)
938{
939 ZERO_STRUCTP(i);
940
941 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
942 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
943 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
944 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
945 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
946
947 return NT_STATUS_OK;
948}
949
950/****************************************************************
951****************************************************************/
952
953static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
954 const struct samr_UserInfo21 *i21,
955 uint32_t auth_flag,
956 struct USER_INFO_11 *i)
957{
958 ZERO_STRUCTP(i);
959
960 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
961 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
962 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
963 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
964 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
965 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
966 i->usri11_auth_flags = auth_flag;
967 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
968 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
969 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
970 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
971 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
972 i->usri11_bad_pw_count = i21->bad_password_count;
973 i->usri11_num_logons = i21->logon_count;
974 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
975 i->usri11_country_code = i21->country_code;
976 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
977 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
978 i->usri11_units_per_week = i21->logon_hours.units_per_week;
979 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
980 i->usri11_code_page = i21->code_page;
981
982 return NT_STATUS_OK;
983}
984
985/****************************************************************
986****************************************************************/
987
988static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
989 const struct samr_UserInfo21 *i21,
990 struct USER_INFO_20 *i)
991{
992 ZERO_STRUCTP(i);
993
994 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
995 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
996 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
997 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
998 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
999 i->usri20_user_id = i21->rid;
1000
1001 return NT_STATUS_OK;
1002}
1003
1004/****************************************************************
1005****************************************************************/
1006
1007static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1008 const struct samr_UserInfo21 *i21,
1009 struct dom_sid *domain_sid,
1010 struct USER_INFO_23 *i)
1011{
1012 struct dom_sid sid;
1013
1014 ZERO_STRUCTP(i);
1015
1016 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1017 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1018 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1019 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1020 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1021 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1022 return NT_STATUS_NO_MEMORY;
1023 }
1024 i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
1025
1026 return NT_STATUS_OK;
1027}
1028
1029/****************************************************************
1030****************************************************************/
1031
1032static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1033 struct rpc_pipe_client *pipe_cli,
1034 struct dom_sid *domain_sid,
1035 struct policy_handle *domain_handle,
1036 struct policy_handle *builtin_handle,
1037 const char *user_name,
1038 uint32_t rid,
1039 uint32_t level,
1040 uint8_t **buffer,
1041 uint32_t *num_entries)
1042{
1043 NTSTATUS status;
1044
1045 struct samr_UserInfo21 *info21 = NULL;
1046 struct sec_desc_buf *sec_desc = NULL;
1047 uint32_t auth_flag = 0;
1048
1049 struct USER_INFO_0 info0;
1050 struct USER_INFO_1 info1;
1051 struct USER_INFO_2 info2;
1052 struct USER_INFO_3 info3;
1053 struct USER_INFO_4 info4;
1054 struct USER_INFO_10 info10;
1055 struct USER_INFO_11 info11;
1056 struct USER_INFO_20 info20;
1057 struct USER_INFO_23 info23;
1058
1059 switch (level) {
1060 case 0:
1061 case 1:
1062 case 2:
1063 case 3:
1064 case 4:
1065 case 10:
1066 case 11:
1067 case 20:
1068 case 23:
1069 break;
1070 default:
1071 return NT_STATUS_INVALID_LEVEL;
1072 }
1073
1074 if (level == 0) {
1075 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1076 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1077
1078 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1079 (struct USER_INFO_0 **)buffer, num_entries);
1080
1081 return NT_STATUS_OK;
1082 }
1083
1084 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1085 domain_handle,
1086 builtin_handle,
1087 user_name,
1088 domain_sid,
1089 rid,
1090 level,
1091 &info21,
1092 &sec_desc,
1093 &auth_flag);
1094
1095 if (!NT_STATUS_IS_OK(status)) {
1096 goto done;
1097 }
1098
1099 switch (level) {
1100 case 0:
1101 /* already returned above */
1102 break;
1103 case 1:
1104 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1105 NT_STATUS_NOT_OK_RETURN(status);
1106
1107 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1108 (struct USER_INFO_1 **)buffer, num_entries);
1109
1110 break;
1111 case 2:
1112 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1113 NT_STATUS_NOT_OK_RETURN(status);
1114
1115 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1116 (struct USER_INFO_2 **)buffer, num_entries);
1117
1118 break;
1119 case 3:
1120 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1121 NT_STATUS_NOT_OK_RETURN(status);
1122
1123 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1124 (struct USER_INFO_3 **)buffer, num_entries);
1125
1126 break;
1127 case 4:
1128 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1129 NT_STATUS_NOT_OK_RETURN(status);
1130
1131 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1132 (struct USER_INFO_4 **)buffer, num_entries);
1133
1134 break;
1135 case 10:
1136 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1137 NT_STATUS_NOT_OK_RETURN(status);
1138
1139 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1140 (struct USER_INFO_10 **)buffer, num_entries);
1141
1142 break;
1143 case 11:
1144 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1145 NT_STATUS_NOT_OK_RETURN(status);
1146
1147 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1148 (struct USER_INFO_11 **)buffer, num_entries);
1149
1150 break;
1151 case 20:
1152 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1153 NT_STATUS_NOT_OK_RETURN(status);
1154
1155 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1156 (struct USER_INFO_20 **)buffer, num_entries);
1157
1158 break;
1159 case 23:
1160 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1161 NT_STATUS_NOT_OK_RETURN(status);
1162
1163 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1164 (struct USER_INFO_23 **)buffer, num_entries);
1165 break;
1166 default:
1167 return NT_STATUS_INVALID_LEVEL;
1168 }
1169
1170 done:
1171 return status;
1172}
1173
1174/****************************************************************
1175****************************************************************/
1176
1177WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1178 struct NetUserEnum *r)
1179{
1180 struct rpc_pipe_client *pipe_cli = NULL;
1181 struct policy_handle connect_handle;
1182 struct dom_sid2 *domain_sid = NULL;
1183 struct policy_handle domain_handle, builtin_handle;
1184 struct samr_SamArray *sam = NULL;
1185 uint32_t filter = ACB_NORMAL;
1186 int i;
1187 uint32_t entries_read = 0;
1188
1189 NTSTATUS status = NT_STATUS_OK;
1190 WERROR werr;
1191
1192 ZERO_STRUCT(connect_handle);
1193 ZERO_STRUCT(domain_handle);
1194 ZERO_STRUCT(builtin_handle);
1195
1196 if (!r->out.buffer) {
1197 return WERR_INVALID_PARAM;
1198 }
1199
1200 *r->out.buffer = NULL;
1201 *r->out.entries_read = 0;
1202
1203 switch (r->in.level) {
1204 case 0:
1205 case 1:
1206 case 2:
1207 case 3:
1208 case 4:
1209 case 10:
1210 case 11:
1211 case 20:
1212 case 23:
1213 break;
1214 default:
1215 return WERR_UNKNOWN_LEVEL;
1216 }
1217
1218 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1219 &ndr_table_samr.syntax_id,
1220 &pipe_cli);
1221 if (!W_ERROR_IS_OK(werr)) {
1222 goto done;
1223 }
1224
1225 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1226 SAMR_ACCESS_ENUM_DOMAINS |
1227 SAMR_ACCESS_LOOKUP_DOMAIN,
1228 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1229 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1230 &connect_handle,
1231 &builtin_handle);
1232 if (!W_ERROR_IS_OK(werr)) {
1233 goto done;
1234 }
1235
1236 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1237 SAMR_ACCESS_ENUM_DOMAINS |
1238 SAMR_ACCESS_LOOKUP_DOMAIN,
1239 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1240 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1241 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1242 &connect_handle,
1243 &domain_handle,
1244 &domain_sid);
1245 if (!W_ERROR_IS_OK(werr)) {
1246 goto done;
1247 }
1248
1249 switch (r->in.filter) {
1250 case FILTER_NORMAL_ACCOUNT:
1251 filter = ACB_NORMAL;
1252 break;
1253 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1254 filter = ACB_TEMPDUP;
1255 break;
1256 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1257 filter = ACB_DOMTRUST;
1258 break;
1259 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1260 filter = ACB_WSTRUST;
1261 break;
1262 case FILTER_SERVER_TRUST_ACCOUNT:
1263 filter = ACB_SVRTRUST;
1264 break;
1265 default:
1266 break;
1267 }
1268
1269 status = rpccli_samr_EnumDomainUsers(pipe_cli,
1270 ctx,
1271 &domain_handle,
1272 r->in.resume_handle,
1273 filter,
1274 &sam,
1275 r->in.prefmaxlen,
1276 &entries_read);
1277 werr = ntstatus_to_werror(status);
1278 if (NT_STATUS_IS_ERR(status)) {
1279 goto done;
1280 }
1281
1282 for (i=0; i < sam->count; i++) {
1283
1284 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1285 domain_sid,
1286 &domain_handle,
1287 &builtin_handle,
1288 sam->entries[i].name.string,
1289 sam->entries[i].idx,
1290 r->in.level,
1291 r->out.buffer,
1292 r->out.entries_read);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 werr = ntstatus_to_werror(status);
1295 goto done;
1296 }
1297 }
1298
1299 done:
1300 /* if last query */
1301 if (NT_STATUS_IS_OK(status) ||
1302 NT_STATUS_IS_ERR(status)) {
1303
1304 if (ctx->disable_policy_handle_cache) {
1305 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1306 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1307 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1308 }
1309 }
1310
1311 return werr;
1312}
1313
1314/****************************************************************
1315****************************************************************/
1316
1317WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1318 struct NetUserEnum *r)
1319{
1320 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1321}
1322
1323/****************************************************************
1324****************************************************************/
1325
1326static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1327 struct samr_DispInfoGeneral *info,
1328 uint32_t *entries_read,
1329 void **buffer)
1330{
1331 struct NET_DISPLAY_USER *user = NULL;
1332 int i;
1333
1334 user = TALLOC_ZERO_ARRAY(mem_ctx,
1335 struct NET_DISPLAY_USER,
1336 info->count);
1337 W_ERROR_HAVE_NO_MEMORY(user);
1338
1339 for (i = 0; i < info->count; i++) {
1340 user[i].usri1_name = talloc_strdup(mem_ctx,
1341 info->entries[i].account_name.string);
1342 user[i].usri1_comment = talloc_strdup(mem_ctx,
1343 info->entries[i].description.string);
1344 user[i].usri1_flags =
1345 info->entries[i].acct_flags;
1346 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1347 info->entries[i].full_name.string);
1348 user[i].usri1_user_id =
1349 info->entries[i].rid;
1350 user[i].usri1_next_index =
1351 info->entries[i].idx;
1352
1353 if (!user[i].usri1_name) {
1354 return WERR_NOMEM;
1355 }
1356 }
1357
1358 *buffer = talloc_memdup(mem_ctx, user,
1359 sizeof(struct NET_DISPLAY_USER) * info->count);
1360 W_ERROR_HAVE_NO_MEMORY(*buffer);
1361
1362 *entries_read = info->count;
1363
1364 return WERR_OK;
1365}
1366
1367/****************************************************************
1368****************************************************************/
1369
1370static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1371 struct samr_DispInfoFull *info,
1372 uint32_t *entries_read,
1373 void **buffer)
1374{
1375 struct NET_DISPLAY_MACHINE *machine = NULL;
1376 int i;
1377
1378 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1379 struct NET_DISPLAY_MACHINE,
1380 info->count);
1381 W_ERROR_HAVE_NO_MEMORY(machine);
1382
1383 for (i = 0; i < info->count; i++) {
1384 machine[i].usri2_name = talloc_strdup(mem_ctx,
1385 info->entries[i].account_name.string);
1386 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1387 info->entries[i].description.string);
1388 machine[i].usri2_flags =
1389 info->entries[i].acct_flags;
1390 machine[i].usri2_user_id =
1391 info->entries[i].rid;
1392 machine[i].usri2_next_index =
1393 info->entries[i].idx;
1394
1395 if (!machine[i].usri2_name) {
1396 return WERR_NOMEM;
1397 }
1398 }
1399
1400 *buffer = talloc_memdup(mem_ctx, machine,
1401 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1402 W_ERROR_HAVE_NO_MEMORY(*buffer);
1403
1404 *entries_read = info->count;
1405
1406 return WERR_OK;
1407}
1408
1409/****************************************************************
1410****************************************************************/
1411
1412static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1413 struct samr_DispInfoFullGroups *info,
1414 uint32_t *entries_read,
1415 void **buffer)
1416{
1417 struct NET_DISPLAY_GROUP *group = NULL;
1418 int i;
1419
1420 group = TALLOC_ZERO_ARRAY(mem_ctx,
1421 struct NET_DISPLAY_GROUP,
1422 info->count);
1423 W_ERROR_HAVE_NO_MEMORY(group);
1424
1425 for (i = 0; i < info->count; i++) {
1426 group[i].grpi3_name = talloc_strdup(mem_ctx,
1427 info->entries[i].account_name.string);
1428 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1429 info->entries[i].description.string);
1430 group[i].grpi3_group_id =
1431 info->entries[i].rid;
1432 group[i].grpi3_attributes =
1433 info->entries[i].acct_flags;
1434 group[i].grpi3_next_index =
1435 info->entries[i].idx;
1436
1437 if (!group[i].grpi3_name) {
1438 return WERR_NOMEM;
1439 }
1440 }
1441
1442 *buffer = talloc_memdup(mem_ctx, group,
1443 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1444 W_ERROR_HAVE_NO_MEMORY(*buffer);
1445
1446 *entries_read = info->count;
1447
1448 return WERR_OK;
1449
1450}
1451
1452/****************************************************************
1453****************************************************************/
1454
1455static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1456 union samr_DispInfo *info,
1457 uint32_t level,
1458 uint32_t *entries_read,
1459 void **buffer)
1460{
1461 switch (level) {
1462 case 1:
1463 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1464 &info->info1,
1465 entries_read,
1466 buffer);
1467 case 2:
1468 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1469 &info->info2,
1470 entries_read,
1471 buffer);
1472 case 3:
1473 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1474 &info->info3,
1475 entries_read,
1476 buffer);
1477 default:
1478 break;
1479 }
1480
1481 return WERR_UNKNOWN_LEVEL;
1482}
1483
1484/****************************************************************
1485****************************************************************/
1486
1487WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1488 struct NetQueryDisplayInformation *r)
1489{
1490 struct rpc_pipe_client *pipe_cli = NULL;
1491 struct policy_handle connect_handle;
1492 struct dom_sid2 *domain_sid = NULL;
1493 struct policy_handle domain_handle;
1494 union samr_DispInfo info;
1495
1496 uint32_t total_size = 0;
1497 uint32_t returned_size = 0;
1498
1499 NTSTATUS status = NT_STATUS_OK;
1500 WERROR werr;
1501 WERROR werr_tmp;
1502
1503 *r->out.entries_read = 0;
1504
1505 ZERO_STRUCT(connect_handle);
1506 ZERO_STRUCT(domain_handle);
1507
1508 switch (r->in.level) {
1509 case 1:
1510 case 2:
1511 case 3:
1512 break;
1513 default:
1514 return WERR_UNKNOWN_LEVEL;
1515 }
1516
1517 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1518 &ndr_table_samr.syntax_id,
1519 &pipe_cli);
1520 if (!W_ERROR_IS_OK(werr)) {
1521 goto done;
1522 }
1523
1524 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1525 SAMR_ACCESS_ENUM_DOMAINS |
1526 SAMR_ACCESS_LOOKUP_DOMAIN,
1527 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1528 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1529 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1530 &connect_handle,
1531 &domain_handle,
1532 &domain_sid);
1533 if (!W_ERROR_IS_OK(werr)) {
1534 goto done;
1535 }
1536
1537 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1538 ctx,
1539 &domain_handle,
1540 r->in.level,
1541 r->in.idx,
1542 r->in.entries_requested,
1543 r->in.prefmaxlen,
1544 &total_size,
1545 &returned_size,
1546 &info);
1547 werr = ntstatus_to_werror(status);
1548 if (NT_STATUS_IS_ERR(status)) {
1549 goto done;
1550 }
1551
1552 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1553 r->in.level,
1554 r->out.entries_read,
1555 r->out.buffer);
1556 if (!W_ERROR_IS_OK(werr_tmp)) {
1557 werr = werr_tmp;
1558 }
1559 done:
1560 /* if last query */
1561 if (NT_STATUS_IS_OK(status) ||
1562 NT_STATUS_IS_ERR(status)) {
1563
1564 if (ctx->disable_policy_handle_cache) {
1565 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1566 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1567 }
1568 }
1569
1570 return werr;
1571
1572}
1573
1574/****************************************************************
1575****************************************************************/
1576
1577
1578WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1579 struct NetQueryDisplayInformation *r)
1580{
1581 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1582}
1583
1584/****************************************************************
1585****************************************************************/
1586
1587WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1588 struct NetUserChangePassword *r)
1589{
1590 return WERR_NOT_SUPPORTED;
1591}
1592
1593/****************************************************************
1594****************************************************************/
1595
1596WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1597 struct NetUserChangePassword *r)
1598{
1599 return WERR_NOT_SUPPORTED;
1600}
1601
1602/****************************************************************
1603****************************************************************/
1604
1605WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1606 struct NetUserGetInfo *r)
1607{
1608 struct rpc_pipe_client *pipe_cli = NULL;
1609 NTSTATUS status;
1610 WERROR werr;
1611
1612 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1613 struct lsa_String lsa_account_name;
1614 struct dom_sid2 *domain_sid = NULL;
1615 struct samr_Ids user_rids, name_types;
1616 uint32_t num_entries = 0;
1617
1618 ZERO_STRUCT(connect_handle);
1619 ZERO_STRUCT(domain_handle);
1620 ZERO_STRUCT(builtin_handle);
1621 ZERO_STRUCT(user_handle);
1622
1623 if (!r->out.buffer) {
1624 return WERR_INVALID_PARAM;
1625 }
1626
1627 switch (r->in.level) {
1628 case 0:
1629 case 1:
1630 case 2:
1631 case 3:
1632 case 4:
1633 case 10:
1634 case 11:
1635 case 20:
1636 case 23:
1637 break;
1638 default:
1639 werr = WERR_UNKNOWN_LEVEL;
1640 goto done;
1641 }
1642
1643 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1644 &ndr_table_samr.syntax_id,
1645 &pipe_cli);
1646 if (!W_ERROR_IS_OK(werr)) {
1647 goto done;
1648 }
1649
1650 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1651 SAMR_ACCESS_ENUM_DOMAINS |
1652 SAMR_ACCESS_LOOKUP_DOMAIN,
1653 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1654 &connect_handle,
1655 &domain_handle,
1656 &domain_sid);
1657 if (!W_ERROR_IS_OK(werr)) {
1658 goto done;
1659 }
1660
1661 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1662 SAMR_ACCESS_ENUM_DOMAINS |
1663 SAMR_ACCESS_LOOKUP_DOMAIN,
1664 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1665 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1666 &connect_handle,
1667 &builtin_handle);
1668 if (!W_ERROR_IS_OK(werr)) {
1669 goto done;
1670 }
1671
1672 init_lsa_String(&lsa_account_name, r->in.user_name);
1673
1674 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1675 &domain_handle,
1676 1,
1677 &lsa_account_name,
1678 &user_rids,
1679 &name_types);
1680 if (!NT_STATUS_IS_OK(status)) {
1681 werr = ntstatus_to_werror(status);
1682 goto done;
1683 }
1684
1685 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1686 domain_sid,
1687 &domain_handle,
1688 &builtin_handle,
1689 r->in.user_name,
1690 user_rids.ids[0],
1691 r->in.level,
1692 r->out.buffer,
1693 &num_entries);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 werr = ntstatus_to_werror(status);
1696 goto done;
1697 }
1698
1699 done:
1700 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1701 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1702 }
1703
1704 if (ctx->disable_policy_handle_cache) {
1705 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1706 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1707 }
1708
1709 return werr;
1710}
1711
1712/****************************************************************
1713****************************************************************/
1714
1715WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1716 struct NetUserGetInfo *r)
1717{
1718 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1719}
1720
1721/****************************************************************
1722****************************************************************/
1723
1724WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1725 struct NetUserSetInfo *r)
1726{
1727 struct rpc_pipe_client *pipe_cli = NULL;
1728 NTSTATUS status;
1729 WERROR werr;
1730
1731 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1732 struct lsa_String lsa_account_name;
1733 struct dom_sid2 *domain_sid = NULL;
1734 struct samr_Ids user_rids, name_types;
1735 uint32_t user_mask = 0;
1736
1737 struct USER_INFO_X uX;
1738
1739 ZERO_STRUCT(connect_handle);
1740 ZERO_STRUCT(domain_handle);
1741 ZERO_STRUCT(builtin_handle);
1742 ZERO_STRUCT(user_handle);
1743
1744 if (!r->in.buffer) {
1745 return WERR_INVALID_PARAM;
1746 }
1747
1748 switch (r->in.level) {
1749 case 0:
1750 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1751 break;
1752 case 1003:
1753 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1754 break;
1755 case 1006:
1756 case 1007:
1757 case 1009:
1758 case 1011:
1759 case 1014:
1760 case 1052:
1761 case 1053:
1762 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1763 break;
1764 case 1012:
1765 case 1024:
1766 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1767 case 1051:
1768 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1769 SAMR_USER_ACCESS_GET_GROUPS;
1770 break;
1771 case 3:
1772 user_mask = STD_RIGHT_READ_CONTROL_ACCESS |
1773 STD_RIGHT_WRITE_DAC_ACCESS |
1774 SAMR_USER_ACCESS_GET_GROUPS |
1775 SAMR_USER_ACCESS_SET_PASSWORD |
1776 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1777 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1778 SAMR_USER_ACCESS_SET_LOC_COM;
1779 break;
1780 case 1:
1781 case 2:
1782 case 4:
1783 case 21:
1784 case 22:
1785 case 1005:
1786 case 1008:
1787 case 1010:
1788 case 1017:
1789 case 1020:
1790 werr = WERR_NOT_SUPPORTED;
1791 goto done;
1792 default:
1793 werr = WERR_UNKNOWN_LEVEL;
1794 goto done;
1795 }
1796
1797 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1798 &ndr_table_samr.syntax_id,
1799 &pipe_cli);
1800 if (!W_ERROR_IS_OK(werr)) {
1801 goto done;
1802 }
1803
1804 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1805 SAMR_ACCESS_ENUM_DOMAINS |
1806 SAMR_ACCESS_LOOKUP_DOMAIN,
1807 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1808 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1809 &connect_handle,
1810 &domain_handle,
1811 &domain_sid);
1812 if (!W_ERROR_IS_OK(werr)) {
1813 goto done;
1814 }
1815
1816 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1817 SAMR_ACCESS_ENUM_DOMAINS |
1818 SAMR_ACCESS_LOOKUP_DOMAIN,
1819 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1820 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1821 &connect_handle,
1822 &builtin_handle);
1823 if (!W_ERROR_IS_OK(werr)) {
1824 goto done;
1825 }
1826
1827 init_lsa_String(&lsa_account_name, r->in.user_name);
1828
1829 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1830 &domain_handle,
1831 1,
1832 &lsa_account_name,
1833 &user_rids,
1834 &name_types);
1835 if (!NT_STATUS_IS_OK(status)) {
1836 werr = ntstatus_to_werror(status);
1837 goto done;
1838 }
1839
1840 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1841 &domain_handle,
1842 user_mask,
1843 user_rids.ids[0],
1844 &user_handle);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 werr = ntstatus_to_werror(status);
1847 goto done;
1848 }
1849
1850 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 werr = ntstatus_to_werror(status);
1853 goto done;
1854 }
1855
1856 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1857 &pipe_cli->auth->user_session_key,
1858 &user_handle,
1859 &uX);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 werr = ntstatus_to_werror(status);
1862 goto done;
1863 }
1864
1865 werr = WERR_OK;
1866
1867 done:
1868 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1869 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1870 }
1871
1872 if (ctx->disable_policy_handle_cache) {
1873 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1874 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1875 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1876 }
1877
1878 return werr;
1879}
1880
1881/****************************************************************
1882****************************************************************/
1883
1884WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1885 struct NetUserSetInfo *r)
1886{
1887 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1888}
1889
1890/****************************************************************
1891****************************************************************/
1892
1893static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1894 struct rpc_pipe_client *pipe_cli,
1895 struct policy_handle *domain_handle,
1896 struct samr_DomInfo1 *info1,
1897 struct samr_DomInfo3 *info3,
1898 struct samr_DomInfo5 *info5,
1899 struct samr_DomInfo6 *info6,
1900 struct samr_DomInfo7 *info7,
1901 struct samr_DomInfo12 *info12)
1902{
1903 NTSTATUS status;
1904 union samr_DomainInfo *dom_info = NULL;
1905
1906 if (info1) {
1907 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1908 domain_handle,
1909 1,
1910 &dom_info);
1911 NT_STATUS_NOT_OK_RETURN(status);
1912
1913 *info1 = dom_info->info1;
1914 }
1915
1916 if (info3) {
1917 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1918 domain_handle,
1919 3,
1920 &dom_info);
1921 NT_STATUS_NOT_OK_RETURN(status);
1922
1923 *info3 = dom_info->info3;
1924 }
1925
1926 if (info5) {
1927 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1928 domain_handle,
1929 5,
1930 &dom_info);
1931 NT_STATUS_NOT_OK_RETURN(status);
1932
1933 *info5 = dom_info->info5;
1934 }
1935
1936 if (info6) {
1937 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1938 domain_handle,
1939 6,
1940 &dom_info);
1941 NT_STATUS_NOT_OK_RETURN(status);
1942
1943 *info6 = dom_info->info6;
1944 }
1945
1946 if (info7) {
1947 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1948 domain_handle,
1949 7,
1950 &dom_info);
1951 NT_STATUS_NOT_OK_RETURN(status);
1952
1953 *info7 = dom_info->info7;
1954 }
1955
1956 if (info12) {
1957 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1958 domain_handle,
1959 12,
1960 &dom_info);
1961 NT_STATUS_NOT_OK_RETURN(status);
1962
1963 *info12 = dom_info->info12;
1964 }
1965
1966 return NT_STATUS_OK;
1967}
1968
1969/****************************************************************
1970****************************************************************/
1971
1972static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1973 struct rpc_pipe_client *pipe_cli,
1974 struct policy_handle *domain_handle,
1975 struct USER_MODALS_INFO_0 *info0)
1976{
1977 NTSTATUS status;
1978 struct samr_DomInfo1 dom_info1;
1979 struct samr_DomInfo3 dom_info3;
1980
1981 ZERO_STRUCTP(info0);
1982
1983 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1984 pipe_cli,
1985 domain_handle,
1986 &dom_info1,
1987 &dom_info3,
1988 NULL,
1989 NULL,
1990 NULL,
1991 NULL);
1992 NT_STATUS_NOT_OK_RETURN(status);
1993
1994 info0->usrmod0_min_passwd_len =
1995 dom_info1.min_password_length;
1996 info0->usrmod0_max_passwd_age =
1997 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1998 info0->usrmod0_min_passwd_age =
1999 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2000 info0->usrmod0_password_hist_len =
2001 dom_info1.password_history_length;
2002
2003 info0->usrmod0_force_logoff =
2004 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2005
2006 return NT_STATUS_OK;
2007}
2008
2009/****************************************************************
2010****************************************************************/
2011
2012static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2013 struct rpc_pipe_client *pipe_cli,
2014 struct policy_handle *domain_handle,
2015 struct USER_MODALS_INFO_1 *info1)
2016{
2017 NTSTATUS status;
2018 struct samr_DomInfo6 dom_info6;
2019 struct samr_DomInfo7 dom_info7;
2020
2021 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2022 pipe_cli,
2023 domain_handle,
2024 NULL,
2025 NULL,
2026 NULL,
2027 &dom_info6,
2028 &dom_info7,
2029 NULL);
2030 NT_STATUS_NOT_OK_RETURN(status);
2031
2032 info1->usrmod1_primary =
2033 talloc_strdup(mem_ctx, dom_info6.primary.string);
2034
2035 info1->usrmod1_role = dom_info7.role;
2036
2037 return NT_STATUS_OK;
2038}
2039
2040/****************************************************************
2041****************************************************************/
2042
2043static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2044 struct rpc_pipe_client *pipe_cli,
2045 struct policy_handle *domain_handle,
2046 struct dom_sid *domain_sid,
2047 struct USER_MODALS_INFO_2 *info2)
2048{
2049 NTSTATUS status;
2050 struct samr_DomInfo5 dom_info5;
2051
2052 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2053 pipe_cli,
2054 domain_handle,
2055 NULL,
2056 NULL,
2057 &dom_info5,
2058 NULL,
2059 NULL,
2060 NULL);
2061 NT_STATUS_NOT_OK_RETURN(status);
2062
2063 info2->usrmod2_domain_name =
2064 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2065 info2->usrmod2_domain_id =
2066 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
2067
2068 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2069 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2070
2071 return NT_STATUS_OK;
2072}
2073
2074/****************************************************************
2075****************************************************************/
2076
2077static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2078 struct rpc_pipe_client *pipe_cli,
2079 struct policy_handle *domain_handle,
2080 struct USER_MODALS_INFO_3 *info3)
2081{
2082 NTSTATUS status;
2083 struct samr_DomInfo12 dom_info12;
2084
2085 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2086 pipe_cli,
2087 domain_handle,
2088 NULL,
2089 NULL,
2090 NULL,
2091 NULL,
2092 NULL,
2093 &dom_info12);
2094 NT_STATUS_NOT_OK_RETURN(status);
2095
2096 info3->usrmod3_lockout_duration =
2097 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2098 info3->usrmod3_lockout_observation_window =
2099 nt_time_to_unix_abs(&dom_info12.lockout_window);
2100 info3->usrmod3_lockout_threshold =
2101 dom_info12.lockout_threshold;
2102
2103 return NT_STATUS_OK;
2104}
2105
2106/****************************************************************
2107****************************************************************/
2108
2109static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2110 struct rpc_pipe_client *pipe_cli,
2111 uint32_t level,
2112 struct policy_handle *domain_handle,
2113 struct dom_sid *domain_sid,
2114 uint8_t **buffer)
2115{
2116 NTSTATUS status;
2117
2118 struct USER_MODALS_INFO_0 info0;
2119 struct USER_MODALS_INFO_1 info1;
2120 struct USER_MODALS_INFO_2 info2;
2121 struct USER_MODALS_INFO_3 info3;
2122
2123 if (!buffer) {
2124 return ERROR_INSUFFICIENT_BUFFER;
2125 }
2126
2127 switch (level) {
2128 case 0:
2129 status = query_USER_MODALS_INFO_0(mem_ctx,
2130 pipe_cli,
2131 domain_handle,
2132 &info0);
2133 NT_STATUS_NOT_OK_RETURN(status);
2134
2135 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2136 sizeof(info0));
2137 break;
2138
2139 case 1:
2140 status = query_USER_MODALS_INFO_1(mem_ctx,
2141 pipe_cli,
2142 domain_handle,
2143 &info1);
2144 NT_STATUS_NOT_OK_RETURN(status);
2145
2146 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2147 sizeof(info1));
2148 break;
2149 case 2:
2150 status = query_USER_MODALS_INFO_2(mem_ctx,
2151 pipe_cli,
2152 domain_handle,
2153 domain_sid,
2154 &info2);
2155 NT_STATUS_NOT_OK_RETURN(status);
2156
2157 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2158 sizeof(info2));
2159 break;
2160 case 3:
2161 status = query_USER_MODALS_INFO_3(mem_ctx,
2162 pipe_cli,
2163 domain_handle,
2164 &info3);
2165 NT_STATUS_NOT_OK_RETURN(status);
2166
2167 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2168 sizeof(info3));
2169 break;
2170 default:
2171 break;
2172 }
2173
2174 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2175
2176 return NT_STATUS_OK;
2177}
2178
2179/****************************************************************
2180****************************************************************/
2181
2182WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2183 struct NetUserModalsGet *r)
2184{
2185 struct rpc_pipe_client *pipe_cli = NULL;
2186 NTSTATUS status;
2187 WERROR werr;
2188
2189 struct policy_handle connect_handle, domain_handle;
2190 struct dom_sid2 *domain_sid = NULL;
2191 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2192
2193 ZERO_STRUCT(connect_handle);
2194 ZERO_STRUCT(domain_handle);
2195
2196 if (!r->out.buffer) {
2197 return WERR_INVALID_PARAM;
2198 }
2199
2200 switch (r->in.level) {
2201 case 0:
2202 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2203 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2204 break;
2205 case 1:
2206 case 2:
2207 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2208 break;
2209 case 3:
2210 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2211 break;
2212 default:
2213 werr = WERR_UNKNOWN_LEVEL;
2214 goto done;
2215 }
2216
2217 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2218 &ndr_table_samr.syntax_id,
2219 &pipe_cli);
2220 if (!W_ERROR_IS_OK(werr)) {
2221 goto done;
2222 }
2223
2224 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2225 SAMR_ACCESS_ENUM_DOMAINS |
2226 SAMR_ACCESS_LOOKUP_DOMAIN,
2227 access_mask,
2228 &connect_handle,
2229 &domain_handle,
2230 &domain_sid);
2231 if (!W_ERROR_IS_OK(werr)) {
2232 goto done;
2233 }
2234
2235 /* 0: 1 + 3 */
2236 /* 1: 6 + 7 */
2237 /* 2: 5 */
2238 /* 3: 12 (DomainInfo2) */
2239
2240 status = query_USER_MODALS_INFO_to_buffer(ctx,
2241 pipe_cli,
2242 r->in.level,
2243 &domain_handle,
2244 domain_sid,
2245 r->out.buffer);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 werr = ntstatus_to_werror(status);
2248 goto done;
2249 }
2250
2251 done:
2252 if (ctx->disable_policy_handle_cache) {
2253 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2254 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2255 }
2256
2257 return werr;
2258}
2259
2260/****************************************************************
2261****************************************************************/
2262
2263WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2264 struct NetUserModalsGet *r)
2265{
2266 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2267}
2268
2269/****************************************************************
2270****************************************************************/
2271
2272static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2273 struct rpc_pipe_client *pipe_cli,
2274 struct policy_handle *domain_handle,
2275 struct samr_DomInfo1 *info1,
2276 struct samr_DomInfo3 *info3,
2277 struct samr_DomInfo12 *info12)
2278{
2279 NTSTATUS status;
2280 union samr_DomainInfo dom_info;
2281
2282 if (info1) {
2283
2284 ZERO_STRUCT(dom_info);
2285
2286 dom_info.info1 = *info1;
2287
2288 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2289 domain_handle,
2290 1,
2291 &dom_info);
2292 NT_STATUS_NOT_OK_RETURN(status);
2293 }
2294
2295 if (info3) {
2296
2297 ZERO_STRUCT(dom_info);
2298
2299 dom_info.info3 = *info3;
2300
2301 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2302 domain_handle,
2303 3,
2304 &dom_info);
2305
2306 NT_STATUS_NOT_OK_RETURN(status);
2307 }
2308
2309 if (info12) {
2310
2311 ZERO_STRUCT(dom_info);
2312
2313 dom_info.info12 = *info12;
2314
2315 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2316 domain_handle,
2317 12,
2318 &dom_info);
2319
2320 NT_STATUS_NOT_OK_RETURN(status);
2321 }
2322
2323 return NT_STATUS_OK;
2324}
2325
2326/****************************************************************
2327****************************************************************/
2328
2329static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2330 struct rpc_pipe_client *pipe_cli,
2331 struct policy_handle *domain_handle,
2332 struct USER_MODALS_INFO_0 *info0)
2333{
2334 NTSTATUS status;
2335 struct samr_DomInfo1 dom_info_1;
2336 struct samr_DomInfo3 dom_info_3;
2337
2338 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2339 pipe_cli,
2340 domain_handle,
2341 &dom_info_1,
2342 &dom_info_3,
2343 NULL,
2344 NULL,
2345 NULL,
2346 NULL);
2347 NT_STATUS_NOT_OK_RETURN(status);
2348
2349 dom_info_1.min_password_length =
2350 info0->usrmod0_min_passwd_len;
2351 dom_info_1.password_history_length =
2352 info0->usrmod0_password_hist_len;
2353
2354 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2355 info0->usrmod0_max_passwd_age);
2356 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2357 info0->usrmod0_min_passwd_age);
2358
2359 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2360 info0->usrmod0_force_logoff);
2361
2362 return set_USER_MODALS_INFO_rpc(mem_ctx,
2363 pipe_cli,
2364 domain_handle,
2365 &dom_info_1,
2366 &dom_info_3,
2367 NULL);
2368}
2369
2370/****************************************************************
2371****************************************************************/
2372
2373static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2374 struct rpc_pipe_client *pipe_cli,
2375 struct policy_handle *domain_handle,
2376 struct USER_MODALS_INFO_3 *info3)
2377{
2378 NTSTATUS status;
2379 struct samr_DomInfo12 dom_info_12;
2380
2381 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2382 pipe_cli,
2383 domain_handle,
2384 NULL,
2385 NULL,
2386 NULL,
2387 NULL,
2388 NULL,
2389 &dom_info_12);
2390 NT_STATUS_NOT_OK_RETURN(status);
2391
2392 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2393 info3->usrmod3_lockout_duration);
2394 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2395 info3->usrmod3_lockout_observation_window);
2396 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2397
2398 return set_USER_MODALS_INFO_rpc(mem_ctx,
2399 pipe_cli,
2400 domain_handle,
2401 NULL,
2402 NULL,
2403 &dom_info_12);
2404}
2405
2406/****************************************************************
2407****************************************************************/
2408
2409static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2410 struct rpc_pipe_client *pipe_cli,
2411 struct policy_handle *domain_handle,
2412 struct USER_MODALS_INFO_1001 *info1001)
2413{
2414 NTSTATUS status;
2415 struct samr_DomInfo1 dom_info_1;
2416
2417 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2418 pipe_cli,
2419 domain_handle,
2420 &dom_info_1,
2421 NULL,
2422 NULL,
2423 NULL,
2424 NULL,
2425 NULL);
2426 NT_STATUS_NOT_OK_RETURN(status);
2427
2428 dom_info_1.min_password_length =
2429 info1001->usrmod1001_min_passwd_len;
2430
2431 return set_USER_MODALS_INFO_rpc(mem_ctx,
2432 pipe_cli,
2433 domain_handle,
2434 &dom_info_1,
2435 NULL,
2436 NULL);
2437}
2438
2439/****************************************************************
2440****************************************************************/
2441
2442static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2443 struct rpc_pipe_client *pipe_cli,
2444 struct policy_handle *domain_handle,
2445 struct USER_MODALS_INFO_1002 *info1002)
2446{
2447 NTSTATUS status;
2448 struct samr_DomInfo1 dom_info_1;
2449
2450 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2451 pipe_cli,
2452 domain_handle,
2453 &dom_info_1,
2454 NULL,
2455 NULL,
2456 NULL,
2457 NULL,
2458 NULL);
2459 NT_STATUS_NOT_OK_RETURN(status);
2460
2461 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2462 info1002->usrmod1002_max_passwd_age);
2463
2464 return set_USER_MODALS_INFO_rpc(mem_ctx,
2465 pipe_cli,
2466 domain_handle,
2467 &dom_info_1,
2468 NULL,
2469 NULL);
2470}
2471
2472/****************************************************************
2473****************************************************************/
2474
2475static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2476 struct rpc_pipe_client *pipe_cli,
2477 struct policy_handle *domain_handle,
2478 struct USER_MODALS_INFO_1003 *info1003)
2479{
2480 NTSTATUS status;
2481 struct samr_DomInfo1 dom_info_1;
2482
2483 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2484 pipe_cli,
2485 domain_handle,
2486 &dom_info_1,
2487 NULL,
2488 NULL,
2489 NULL,
2490 NULL,
2491 NULL);
2492 NT_STATUS_NOT_OK_RETURN(status);
2493
2494 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2495 info1003->usrmod1003_min_passwd_age);
2496
2497 return set_USER_MODALS_INFO_rpc(mem_ctx,
2498 pipe_cli,
2499 domain_handle,
2500 &dom_info_1,
2501 NULL,
2502 NULL);
2503}
2504
2505/****************************************************************
2506****************************************************************/
2507
2508static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2509 struct rpc_pipe_client *pipe_cli,
2510 struct policy_handle *domain_handle,
2511 struct USER_MODALS_INFO_1004 *info1004)
2512{
2513 NTSTATUS status;
2514 struct samr_DomInfo3 dom_info_3;
2515
2516 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2517 pipe_cli,
2518 domain_handle,
2519 NULL,
2520 &dom_info_3,
2521 NULL,
2522 NULL,
2523 NULL,
2524 NULL);
2525 NT_STATUS_NOT_OK_RETURN(status);
2526
2527 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2528 info1004->usrmod1004_force_logoff);
2529
2530 return set_USER_MODALS_INFO_rpc(mem_ctx,
2531 pipe_cli,
2532 domain_handle,
2533 NULL,
2534 &dom_info_3,
2535 NULL);
2536}
2537
2538/****************************************************************
2539****************************************************************/
2540
2541static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2542 struct rpc_pipe_client *pipe_cli,
2543 struct policy_handle *domain_handle,
2544 struct USER_MODALS_INFO_1005 *info1005)
2545{
2546 NTSTATUS status;
2547 struct samr_DomInfo1 dom_info_1;
2548
2549 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2550 pipe_cli,
2551 domain_handle,
2552 &dom_info_1,
2553 NULL,
2554 NULL,
2555 NULL,
2556 NULL,
2557 NULL);
2558 NT_STATUS_NOT_OK_RETURN(status);
2559
2560 dom_info_1.password_history_length =
2561 info1005->usrmod1005_password_hist_len;
2562
2563 return set_USER_MODALS_INFO_rpc(mem_ctx,
2564 pipe_cli,
2565 domain_handle,
2566 &dom_info_1,
2567 NULL,
2568 NULL);
2569}
2570
2571/****************************************************************
2572****************************************************************/
2573
2574static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2575 struct rpc_pipe_client *pipe_cli,
2576 uint32_t level,
2577 struct policy_handle *domain_handle,
2578 struct dom_sid *domain_sid,
2579 uint8_t *buffer)
2580{
2581 struct USER_MODALS_INFO_0 *info0;
2582 struct USER_MODALS_INFO_3 *info3;
2583 struct USER_MODALS_INFO_1001 *info1001;
2584 struct USER_MODALS_INFO_1002 *info1002;
2585 struct USER_MODALS_INFO_1003 *info1003;
2586 struct USER_MODALS_INFO_1004 *info1004;
2587 struct USER_MODALS_INFO_1005 *info1005;
2588
2589 if (!buffer) {
2590 return ERROR_INSUFFICIENT_BUFFER;
2591 }
2592
2593 switch (level) {
2594 case 0:
2595 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2596 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2597 pipe_cli,
2598 domain_handle,
2599 info0);
2600 case 3:
2601 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2602 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2603 pipe_cli,
2604 domain_handle,
2605 info3);
2606 case 1001:
2607 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2608 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2609 pipe_cli,
2610 domain_handle,
2611 info1001);
2612 case 1002:
2613 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2614 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2615 pipe_cli,
2616 domain_handle,
2617 info1002);
2618 case 1003:
2619 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2620 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2621 pipe_cli,
2622 domain_handle,
2623 info1003);
2624 case 1004:
2625 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2626 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2627 pipe_cli,
2628 domain_handle,
2629 info1004);
2630 case 1005:
2631 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2632 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2633 pipe_cli,
2634 domain_handle,
2635 info1005);
2636
2637 default:
2638 break;
2639 }
2640
2641 return NT_STATUS_OK;
2642}
2643
2644/****************************************************************
2645****************************************************************/
2646
2647WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2648 struct NetUserModalsSet *r)
2649{
2650 struct rpc_pipe_client *pipe_cli = NULL;
2651 NTSTATUS status;
2652 WERROR werr;
2653
2654 struct policy_handle connect_handle, domain_handle;
2655 struct dom_sid2 *domain_sid = NULL;
2656 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2657
2658 ZERO_STRUCT(connect_handle);
2659 ZERO_STRUCT(domain_handle);
2660
2661 if (!r->in.buffer) {
2662 return WERR_INVALID_PARAM;
2663 }
2664
2665 switch (r->in.level) {
2666 case 0:
2667 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2668 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2669 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2670 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2671 break;
2672 case 3:
2673 case 1001:
2674 case 1002:
2675 case 1003:
2676 case 1005:
2677 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2678 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2679 break;
2680 case 1004:
2681 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2682 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2683 break;
2684 case 1:
2685 case 2:
2686 case 1006:
2687 case 1007:
2688 werr = WERR_NOT_SUPPORTED;
2689 break;
2690 default:
2691 werr = WERR_UNKNOWN_LEVEL;
2692 goto done;
2693 }
2694
2695 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2696 &ndr_table_samr.syntax_id,
2697 &pipe_cli);
2698 if (!W_ERROR_IS_OK(werr)) {
2699 goto done;
2700 }
2701
2702 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2703 SAMR_ACCESS_ENUM_DOMAINS |
2704 SAMR_ACCESS_LOOKUP_DOMAIN,
2705 access_mask,
2706 &connect_handle,
2707 &domain_handle,
2708 &domain_sid);
2709 if (!W_ERROR_IS_OK(werr)) {
2710 goto done;
2711 }
2712
2713 status = set_USER_MODALS_INFO_buffer(ctx,
2714 pipe_cli,
2715 r->in.level,
2716 &domain_handle,
2717 domain_sid,
2718 r->in.buffer);
2719 if (!NT_STATUS_IS_OK(status)) {
2720 werr = ntstatus_to_werror(status);
2721 goto done;
2722 }
2723
2724 done:
2725 if (ctx->disable_policy_handle_cache) {
2726 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2727 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2728 }
2729
2730 return werr;
2731}
2732
2733/****************************************************************
2734****************************************************************/
2735
2736WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2737 struct NetUserModalsSet *r)
2738{
2739 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2740}
2741
2742/****************************************************************
2743****************************************************************/
2744
2745NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2746 uint32_t level,
2747 const char *group_name,
2748 uint32_t attributes,
2749 uint8_t **buffer,
2750 uint32_t *num_entries)
2751{
2752 struct GROUP_USERS_INFO_0 u0;
2753 struct GROUP_USERS_INFO_1 u1;
2754
2755 switch (level) {
2756 case 0:
2757 if (group_name) {
2758 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2759 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2760 } else {
2761 u0.grui0_name = NULL;
2762 }
2763
2764 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2765 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2766 break;
2767 case 1:
2768 if (group_name) {
2769 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2770 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2771 } else {
2772 u1.grui1_name = NULL;
2773 }
2774
2775 u1.grui1_attributes = attributes;
2776
2777 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2778 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2779 break;
2780 default:
2781 return NT_STATUS_INVALID_INFO_CLASS;
2782 }
2783
2784 return NT_STATUS_OK;
2785}
2786
2787/****************************************************************
2788****************************************************************/
2789
2790WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2791 struct NetUserGetGroups *r)
2792{
2793 struct rpc_pipe_client *pipe_cli = NULL;
2794 struct policy_handle connect_handle, domain_handle, user_handle;
2795 struct lsa_String lsa_account_name;
2796 struct dom_sid2 *domain_sid = NULL;
2797 struct samr_Ids user_rids, name_types;
2798 struct samr_RidWithAttributeArray *rid_array = NULL;
2799 struct lsa_Strings names;
2800 struct samr_Ids types;
2801 uint32_t *rids = NULL;
2802
2803 int i;
2804 uint32_t entries_read = 0;
2805
2806 NTSTATUS status = NT_STATUS_OK;
2807 WERROR werr;
2808
2809 ZERO_STRUCT(connect_handle);
2810 ZERO_STRUCT(domain_handle);
2811
2812 if (!r->out.buffer) {
2813 return WERR_INVALID_PARAM;
2814 }
2815
2816 *r->out.buffer = NULL;
2817 *r->out.entries_read = 0;
2818 *r->out.total_entries = 0;
2819
2820 switch (r->in.level) {
2821 case 0:
2822 case 1:
2823 break;
2824 default:
2825 return WERR_UNKNOWN_LEVEL;
2826 }
2827
2828 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2829 &ndr_table_samr.syntax_id,
2830 &pipe_cli);
2831 if (!W_ERROR_IS_OK(werr)) {
2832 goto done;
2833 }
2834
2835 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2836 SAMR_ACCESS_ENUM_DOMAINS |
2837 SAMR_ACCESS_LOOKUP_DOMAIN,
2838 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2839 &connect_handle,
2840 &domain_handle,
2841 &domain_sid);
2842 if (!W_ERROR_IS_OK(werr)) {
2843 goto done;
2844 }
2845
2846 init_lsa_String(&lsa_account_name, r->in.user_name);
2847
2848 status = rpccli_samr_LookupNames(pipe_cli, ctx,
2849 &domain_handle,
2850 1,
2851 &lsa_account_name,
2852 &user_rids,
2853 &name_types);
2854 if (!NT_STATUS_IS_OK(status)) {
2855 werr = ntstatus_to_werror(status);
2856 goto done;
2857 }
2858
2859 status = rpccli_samr_OpenUser(pipe_cli, ctx,
2860 &domain_handle,
2861 SAMR_USER_ACCESS_GET_GROUPS,
2862 user_rids.ids[0],
2863 &user_handle);
2864 if (!NT_STATUS_IS_OK(status)) {
2865 werr = ntstatus_to_werror(status);
2866 goto done;
2867 }
2868
2869 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2870 &user_handle,
2871 &rid_array);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 werr = ntstatus_to_werror(status);
2874 goto done;
2875 }
2876
2877 rids = talloc_array(ctx, uint32_t, rid_array->count);
2878 if (!rids) {
2879 werr = WERR_NOMEM;
2880 goto done;
2881 }
2882
2883 for (i=0; i < rid_array->count; i++) {
2884 rids[i] = rid_array->rids[i].rid;
2885 }
2886
2887 status = rpccli_samr_LookupRids(pipe_cli, ctx,
2888 &domain_handle,
2889 rid_array->count,
2890 rids,
2891 &names,
2892 &types);
2893 if (!NT_STATUS_IS_OK(status) &&
2894 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
2895 werr = ntstatus_to_werror(status);
2896 goto done;
2897 }
2898
2899 for (i=0; i < names.count; i++) {
2900 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2901 r->in.level,
2902 names.names[i].string,
2903 rid_array->rids[i].attributes,
2904 r->out.buffer,
2905 &entries_read);
2906 if (!NT_STATUS_IS_OK(status)) {
2907 werr = ntstatus_to_werror(status);
2908 goto done;
2909 }
2910 }
2911
2912 *r->out.entries_read = entries_read;
2913 *r->out.total_entries = entries_read;
2914
2915 done:
2916 if (ctx->disable_policy_handle_cache) {
2917 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2918 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2919 }
2920
2921 return werr;
2922}
2923
2924/****************************************************************
2925****************************************************************/
2926
2927WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2928 struct NetUserGetGroups *r)
2929{
2930 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
2931}
2932
2933/****************************************************************
2934****************************************************************/
2935
2936WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
2937 struct NetUserSetGroups *r)
2938{
2939 struct rpc_pipe_client *pipe_cli = NULL;
2940 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
2941 struct lsa_String lsa_account_name;
2942 struct dom_sid2 *domain_sid = NULL;
2943 struct samr_Ids user_rids, name_types;
2944 struct samr_Ids group_rids;
2945 struct samr_RidWithAttributeArray *rid_array = NULL;
2946 struct lsa_String *lsa_names = NULL;
2947
2948 uint32_t *add_rids = NULL;
2949 uint32_t *del_rids = NULL;
2950 size_t num_add_rids = 0;
2951 size_t num_del_rids = 0;
2952
2953 uint32_t *member_rids = NULL;
2954 size_t num_member_rids = 0;
2955
2956 struct GROUP_USERS_INFO_0 *i0 = NULL;
2957 struct GROUP_USERS_INFO_1 *i1 = NULL;
2958
2959 int i, k;
2960
2961 NTSTATUS status = NT_STATUS_OK;
2962 WERROR werr;
2963
2964 ZERO_STRUCT(connect_handle);
2965 ZERO_STRUCT(domain_handle);
2966
2967 if (!r->in.buffer) {
2968 return WERR_INVALID_PARAM;
2969 }
2970
2971 switch (r->in.level) {
2972 case 0:
2973 case 1:
2974 break;
2975 default:
2976 return WERR_UNKNOWN_LEVEL;
2977 }
2978
2979 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2980 &ndr_table_samr.syntax_id,
2981 &pipe_cli);
2982 if (!W_ERROR_IS_OK(werr)) {
2983 goto done;
2984 }
2985
2986 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2987 SAMR_ACCESS_ENUM_DOMAINS |
2988 SAMR_ACCESS_LOOKUP_DOMAIN,
2989 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2990 &connect_handle,
2991 &domain_handle,
2992 &domain_sid);
2993 if (!W_ERROR_IS_OK(werr)) {
2994 goto done;
2995 }
2996
2997 init_lsa_String(&lsa_account_name, r->in.user_name);
2998
2999 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3000 &domain_handle,
3001 1,
3002 &lsa_account_name,
3003 &user_rids,
3004 &name_types);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 werr = ntstatus_to_werror(status);
3007 goto done;
3008 }
3009
3010 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3011 &domain_handle,
3012 SAMR_USER_ACCESS_GET_GROUPS,
3013 user_rids.ids[0],
3014 &user_handle);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 werr = ntstatus_to_werror(status);
3017 goto done;
3018 }
3019
3020 switch (r->in.level) {
3021 case 0:
3022 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3023 break;
3024 case 1:
3025 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3026 break;
3027 }
3028
3029 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3030 if (!lsa_names) {
3031 werr = WERR_NOMEM;
3032 goto done;
3033 }
3034
3035 for (i=0; i < r->in.num_entries; i++) {
3036
3037 switch (r->in.level) {
3038 case 0:
3039 init_lsa_String(&lsa_names[i], i0->grui0_name);
3040 i0++;
3041 break;
3042 case 1:
3043 init_lsa_String(&lsa_names[i], i1->grui1_name);
3044 i1++;
3045 break;
3046 }
3047 }
3048
3049 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3050 &domain_handle,
3051 r->in.num_entries,
3052 lsa_names,
3053 &group_rids,
3054 &name_types);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 werr = ntstatus_to_werror(status);
3057 goto done;
3058 }
3059
3060 member_rids = group_rids.ids;
3061 num_member_rids = group_rids.count;
3062
3063 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3064 &user_handle,
3065 &rid_array);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 werr = ntstatus_to_werror(status);
3068 goto done;
3069 }
3070
3071 /* add list */
3072
3073 for (i=0; i < r->in.num_entries; i++) {
3074 bool already_member = false;
3075 for (k=0; k < rid_array->count; k++) {
3076 if (member_rids[i] == rid_array->rids[k].rid) {
3077 already_member = true;
3078 break;
3079 }
3080 }
3081 if (!already_member) {
3082 if (!add_rid_to_array_unique(ctx,
3083 member_rids[i],
3084 &add_rids, &num_add_rids)) {
3085 werr = WERR_GENERAL_FAILURE;
3086 goto done;
3087 }
3088 }
3089 }
3090
3091 /* del list */
3092
3093 for (k=0; k < rid_array->count; k++) {
3094 bool keep_member = false;
3095 for (i=0; i < r->in.num_entries; i++) {
3096 if (member_rids[i] == rid_array->rids[k].rid) {
3097 keep_member = true;
3098 break;
3099 }
3100 }
3101 if (!keep_member) {
3102 if (!add_rid_to_array_unique(ctx,
3103 rid_array->rids[k].rid,
3104 &del_rids, &num_del_rids)) {
3105 werr = WERR_GENERAL_FAILURE;
3106 goto done;
3107 }
3108 }
3109 }
3110
3111 /* add list */
3112
3113 for (i=0; i < num_add_rids; i++) {
3114 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3115 &domain_handle,
3116 SAMR_GROUP_ACCESS_ADD_MEMBER,
3117 add_rids[i],
3118 &group_handle);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 werr = ntstatus_to_werror(status);
3121 goto done;
3122 }
3123
3124 status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
3125 &group_handle,
3126 user_rids.ids[0],
3127 7 /* ? */);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 werr = ntstatus_to_werror(status);
3130 goto done;
3131 }
3132
3133 if (is_valid_policy_hnd(&group_handle)) {
3134 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3135 }
3136 }
3137
3138 /* del list */
3139
3140 for (i=0; i < num_del_rids; i++) {
3141 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3142 &domain_handle,
3143 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3144 del_rids[i],
3145 &group_handle);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 werr = ntstatus_to_werror(status);
3148 goto done;
3149 }
3150
3151 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
3152 &group_handle,
3153 user_rids.ids[0]);
3154 if (!NT_STATUS_IS_OK(status)) {
3155 werr = ntstatus_to_werror(status);
3156 goto done;
3157 }
3158
3159 if (is_valid_policy_hnd(&group_handle)) {
3160 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3161 }
3162 }
3163
3164 werr = WERR_OK;
3165
3166 done:
3167 if (is_valid_policy_hnd(&group_handle)) {
3168 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3169 }
3170
3171 if (ctx->disable_policy_handle_cache) {
3172 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3173 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3174 }
3175
3176 return werr;
3177}
3178
3179/****************************************************************
3180****************************************************************/
3181
3182WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3183 struct NetUserSetGroups *r)
3184{
3185 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3186}
3187
3188/****************************************************************
3189****************************************************************/
3190
3191static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3192 uint32_t level,
3193 const char *group_name,
3194 uint8_t **buffer,
3195 uint32_t *num_entries)
3196{
3197 struct LOCALGROUP_USERS_INFO_0 u0;
3198
3199 switch (level) {
3200 case 0:
3201 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3202 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3203
3204 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3205 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3206 break;
3207 default:
3208 return NT_STATUS_INVALID_INFO_CLASS;
3209 }
3210
3211 return NT_STATUS_OK;
3212}
3213
3214/****************************************************************
3215****************************************************************/
3216
3217WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3218 struct NetUserGetLocalGroups *r)
3219{
3220 struct rpc_pipe_client *pipe_cli = NULL;
3221 struct policy_handle connect_handle, domain_handle, user_handle,
3222 builtin_handle;
3223 struct lsa_String lsa_account_name;
3224 struct dom_sid2 *domain_sid = NULL;
3225 struct samr_Ids user_rids, name_types;
3226 struct samr_RidWithAttributeArray *rid_array = NULL;
3227 struct lsa_Strings names;
3228 struct samr_Ids types;
3229 uint32_t *rids = NULL;
3230 size_t num_rids = 0;
3231 struct dom_sid user_sid;
3232 struct lsa_SidArray sid_array;
3233 struct samr_Ids domain_rids;
3234 struct samr_Ids builtin_rids;
3235
3236 int i;
3237 uint32_t entries_read = 0;
3238
3239 NTSTATUS status = NT_STATUS_OK;
3240 WERROR werr;
3241
3242 ZERO_STRUCT(connect_handle);
3243 ZERO_STRUCT(domain_handle);
3244
3245 if (!r->out.buffer) {
3246 return WERR_INVALID_PARAM;
3247 }
3248
3249 *r->out.buffer = NULL;
3250 *r->out.entries_read = 0;
3251 *r->out.total_entries = 0;
3252
3253 switch (r->in.level) {
3254 case 0:
3255 case 1:
3256 break;
3257 default:
3258 return WERR_UNKNOWN_LEVEL;
3259 }
3260
3261 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3262 &ndr_table_samr.syntax_id,
3263 &pipe_cli);
3264 if (!W_ERROR_IS_OK(werr)) {
3265 goto done;
3266 }
3267
3268 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3269 SAMR_ACCESS_ENUM_DOMAINS |
3270 SAMR_ACCESS_LOOKUP_DOMAIN,
3271 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3272 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3273 &connect_handle,
3274 &domain_handle,
3275 &domain_sid);
3276 if (!W_ERROR_IS_OK(werr)) {
3277 goto done;
3278 }
3279
3280 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3281 SAMR_ACCESS_ENUM_DOMAINS |
3282 SAMR_ACCESS_LOOKUP_DOMAIN,
3283 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3284 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3285 &connect_handle,
3286 &builtin_handle);
3287 if (!W_ERROR_IS_OK(werr)) {
3288 goto done;
3289 }
3290
3291 init_lsa_String(&lsa_account_name, r->in.user_name);
3292
3293 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3294 &domain_handle,
3295 1,
3296 &lsa_account_name,
3297 &user_rids,
3298 &name_types);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 werr = ntstatus_to_werror(status);
3301 goto done;
3302 }
3303
3304 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3305 &domain_handle,
3306 SAMR_USER_ACCESS_GET_GROUPS,
3307 user_rids.ids[0],
3308 &user_handle);
3309 if (!NT_STATUS_IS_OK(status)) {
3310 werr = ntstatus_to_werror(status);
3311 goto done;
3312 }
3313
3314 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3315 &user_handle,
3316 &rid_array);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 werr = ntstatus_to_werror(status);
3319 goto done;
3320 }
3321
3322 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3323 werr = WERR_NOMEM;
3324 goto done;
3325 }
3326
3327 sid_array.num_sids = rid_array->count + 1;
3328 sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
3329 if (!sid_array.sids) {
3330 werr = WERR_NOMEM;
3331 goto done;
3332 }
3333
3334 sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid);
3335 if (!sid_array.sids[0].sid) {
3336 werr = WERR_NOMEM;
3337 goto done;
3338 }
3339
3340 for (i=0; i < rid_array->count; i++) {
3341 struct dom_sid sid;
3342
3343 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3344 werr = WERR_NOMEM;
3345 goto done;
3346 }
3347
3348 sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid);
3349 if (!sid_array.sids[i+1].sid) {
3350 werr = WERR_NOMEM;
3351 goto done;
3352 }
3353 }
3354
3355 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3356 &domain_handle,
3357 &sid_array,
3358 &domain_rids);
3359 if (!NT_STATUS_IS_OK(status)) {
3360 werr = ntstatus_to_werror(status);
3361 goto done;
3362 }
3363
3364 for (i=0; i < domain_rids.count; i++) {
3365 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3366 &rids, &num_rids)) {
3367 werr = WERR_NOMEM;
3368 goto done;
3369 }
3370 }
3371
3372 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3373 &builtin_handle,
3374 &sid_array,
3375 &builtin_rids);
3376 if (!NT_STATUS_IS_OK(status)) {
3377 werr = ntstatus_to_werror(status);
3378 goto done;
3379 }
3380
3381 for (i=0; i < builtin_rids.count; i++) {
3382 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3383 &rids, &num_rids)) {
3384 werr = WERR_NOMEM;
3385 goto done;
3386 }
3387 }
3388
3389 status = rpccli_samr_LookupRids(pipe_cli, ctx,
3390 &builtin_handle,
3391 num_rids,
3392 rids,
3393 &names,
3394 &types);
3395 if (!NT_STATUS_IS_OK(status)) {
3396 werr = ntstatus_to_werror(status);
3397 goto done;
3398 }
3399
3400 for (i=0; i < names.count; i++) {
3401 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3402 r->in.level,
3403 names.names[i].string,
3404 r->out.buffer,
3405 &entries_read);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 werr = ntstatus_to_werror(status);
3408 goto done;
3409 }
3410 }
3411
3412 *r->out.entries_read = entries_read;
3413 *r->out.total_entries = entries_read;
3414
3415 done:
3416 if (ctx->disable_policy_handle_cache) {
3417 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3418 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3419 }
3420
3421 return werr;
3422}
3423
3424/****************************************************************
3425****************************************************************/
3426
3427WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3428 struct NetUserGetLocalGroups *r)
3429{
3430 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);
3431}
Note: See TracBrowser for help on using the repository browser.