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

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

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