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

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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