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

Last change on this file was 860, checked in by Silvan Scherrer, 11 years ago

Samba 3.6: updated vendor to latest version

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