source: branches/samba-3.5.x/source3/lib/netapi/user.c

Last change on this file was 596, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update trunk to 3.5.8

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