s4-smbtorture: fill PrinterDriverData with more values for consistency test.
[Samba/nascimento.git] / source3 / lib / netapi / user.c
blob1ad4a6f282a090e07121d1f62e24083f579ffc00
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi User Support
4 * Copyright (C) Guenther Deschner 2008
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.
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.
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/>.
20 #include "includes.h"
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
25 #include "lib/netapi/libnetapi.h"
26 #include "../librpc/gen_ndr/cli_samr.h"
28 /****************************************************************
29 ****************************************************************/
31 static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
32 struct samr_UserInfo21 *info21)
34 uint32_t fields_present = 0;
35 struct samr_LogonHours zero_logon_hours;
36 struct lsa_BinaryString zero_parameters;
37 NTTIME password_age;
39 ZERO_STRUCTP(info21);
40 ZERO_STRUCT(zero_logon_hours);
41 ZERO_STRUCT(zero_parameters);
43 if (infoX->usriX_flags) {
44 fields_present |= SAMR_FIELD_ACCT_FLAGS;
46 if (infoX->usriX_name) {
47 fields_present |= SAMR_FIELD_ACCOUNT_NAME;
49 if (infoX->usriX_password) {
50 fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
52 if (infoX->usriX_flags) {
53 fields_present |= SAMR_FIELD_ACCT_FLAGS;
55 if (infoX->usriX_name) {
56 fields_present |= SAMR_FIELD_FULL_NAME;
58 if (infoX->usriX_home_dir) {
59 fields_present |= SAMR_FIELD_HOME_DIRECTORY;
61 if (infoX->usriX_script_path) {
62 fields_present |= SAMR_FIELD_LOGON_SCRIPT;
64 if (infoX->usriX_comment) {
65 fields_present |= SAMR_FIELD_DESCRIPTION;
67 if (infoX->usriX_password_age) {
68 fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
70 if (infoX->usriX_full_name) {
71 fields_present |= SAMR_FIELD_FULL_NAME;
73 if (infoX->usriX_usr_comment) {
74 fields_present |= SAMR_FIELD_COMMENT;
76 if (infoX->usriX_profile) {
77 fields_present |= SAMR_FIELD_PROFILE_PATH;
79 if (infoX->usriX_home_dir_drive) {
80 fields_present |= SAMR_FIELD_HOME_DRIVE;
82 if (infoX->usriX_primary_group_id) {
83 fields_present |= SAMR_FIELD_PRIMARY_GID;
85 if (infoX->usriX_country_code) {
86 fields_present |= SAMR_FIELD_COUNTRY_CODE;
88 if (infoX->usriX_workstations) {
89 fields_present |= SAMR_FIELD_WORKSTATIONS;
92 unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
94 /* TODO: infoX->usriX_priv */
96 info21->last_logon = 0;
97 info21->last_logoff = 0;
98 info21->last_password_change = 0;
99 info21->acct_expiry = 0;
100 info21->allow_password_change = 0;
101 info21->force_password_change = 0;
102 info21->account_name.string = infoX->usriX_name;
103 info21->full_name.string = infoX->usriX_full_name;
104 info21->home_directory.string = infoX->usriX_home_dir;
105 info21->home_drive.string = infoX->usriX_home_dir_drive;
106 info21->logon_script.string = infoX->usriX_script_path;
107 info21->profile_path.string = infoX->usriX_profile;
108 info21->description.string = infoX->usriX_comment;
109 info21->workstations.string = infoX->usriX_workstations;
110 info21->comment.string = infoX->usriX_usr_comment;
111 info21->parameters = zero_parameters;
112 info21->lm_owf_password = zero_parameters;
113 info21->nt_owf_password = zero_parameters;
114 info21->unknown3.string = NULL;
115 info21->buf_count = 0;
116 info21->buffer = NULL;
117 info21->rid = infoX->usriX_user_id;
118 info21->primary_gid = infoX->usriX_primary_group_id;
119 info21->acct_flags = infoX->usriX_flags;
120 info21->fields_present = fields_present;
121 info21->logon_hours = zero_logon_hours;
122 info21->bad_password_count = infoX->usriX_bad_pw_count;
123 info21->logon_count = infoX->usriX_num_logons;
124 info21->country_code = infoX->usriX_country_code;
125 info21->code_page = infoX->usriX_code_page;
126 info21->lm_password_set = 0;
127 info21->nt_password_set = 0;
128 info21->password_expired = infoX->usriX_password_expired;
129 info21->unknown4 = 0;
132 /****************************************************************
133 ****************************************************************/
135 static NTSTATUS construct_USER_INFO_X(uint32_t level,
136 uint8_t *buffer,
137 struct USER_INFO_X *uX)
139 struct USER_INFO_0 *u0 = NULL;
140 struct USER_INFO_1 *u1 = NULL;
141 struct USER_INFO_2 *u2 = NULL;
142 struct USER_INFO_3 *u3 = NULL;
143 struct USER_INFO_1003 *u1003 = NULL;
144 struct USER_INFO_1006 *u1006 = NULL;
145 struct USER_INFO_1007 *u1007 = NULL;
146 struct USER_INFO_1009 *u1009 = NULL;
147 struct USER_INFO_1011 *u1011 = NULL;
148 struct USER_INFO_1012 *u1012 = NULL;
149 struct USER_INFO_1014 *u1014 = NULL;
150 struct USER_INFO_1024 *u1024 = NULL;
151 struct USER_INFO_1051 *u1051 = NULL;
152 struct USER_INFO_1052 *u1052 = NULL;
153 struct USER_INFO_1053 *u1053 = NULL;
155 if (!buffer || !uX) {
156 return NT_STATUS_INVALID_PARAMETER;
159 ZERO_STRUCTP(uX);
161 switch (level) {
162 case 0:
163 u0 = (struct USER_INFO_0 *)buffer;
164 uX->usriX_name = u0->usri0_name;
165 break;
166 case 1:
167 u1 = (struct USER_INFO_1 *)buffer;
168 uX->usriX_name = u1->usri1_name;
169 uX->usriX_password = u1->usri1_password;
170 uX->usriX_password_age = u1->usri1_password_age;
171 uX->usriX_priv = u1->usri1_priv;
172 uX->usriX_home_dir = u1->usri1_home_dir;
173 uX->usriX_comment = u1->usri1_comment;
174 uX->usriX_flags = u1->usri1_flags;
175 uX->usriX_script_path = u1->usri1_script_path;
176 break;
177 case 2:
178 u2 = (struct USER_INFO_2 *)buffer;
179 uX->usriX_name = u2->usri2_name;
180 uX->usriX_password = u2->usri2_password;
181 uX->usriX_password_age = u2->usri2_password_age;
182 uX->usriX_priv = u2->usri2_priv;
183 uX->usriX_home_dir = u2->usri2_home_dir;
184 uX->usriX_comment = u2->usri2_comment;
185 uX->usriX_flags = u2->usri2_flags;
186 uX->usriX_script_path = u2->usri2_script_path;
187 uX->usriX_auth_flags = u2->usri2_auth_flags;
188 uX->usriX_full_name = u2->usri2_full_name;
189 uX->usriX_usr_comment = u2->usri2_usr_comment;
190 uX->usriX_parms = u2->usri2_parms;
191 uX->usriX_workstations = u2->usri2_workstations;
192 uX->usriX_last_logon = u2->usri2_last_logon;
193 uX->usriX_last_logoff = u2->usri2_last_logoff;
194 uX->usriX_acct_expires = u2->usri2_acct_expires;
195 uX->usriX_max_storage = u2->usri2_max_storage;
196 uX->usriX_units_per_week= u2->usri2_units_per_week;
197 uX->usriX_logon_hours = u2->usri2_logon_hours;
198 uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
199 uX->usriX_num_logons = u2->usri2_num_logons;
200 uX->usriX_logon_server = u2->usri2_logon_server;
201 uX->usriX_country_code = u2->usri2_country_code;
202 uX->usriX_code_page = u2->usri2_code_page;
203 break;
204 case 3:
205 u3 = (struct USER_INFO_3 *)buffer;
206 uX->usriX_name = u3->usri3_name;
207 uX->usriX_password_age = u3->usri3_password_age;
208 uX->usriX_priv = u3->usri3_priv;
209 uX->usriX_home_dir = u3->usri3_home_dir;
210 uX->usriX_comment = u3->usri3_comment;
211 uX->usriX_flags = u3->usri3_flags;
212 uX->usriX_script_path = u3->usri3_script_path;
213 uX->usriX_auth_flags = u3->usri3_auth_flags;
214 uX->usriX_full_name = u3->usri3_full_name;
215 uX->usriX_usr_comment = u3->usri3_usr_comment;
216 uX->usriX_parms = u3->usri3_parms;
217 uX->usriX_workstations = u3->usri3_workstations;
218 uX->usriX_last_logon = u3->usri3_last_logon;
219 uX->usriX_last_logoff = u3->usri3_last_logoff;
220 uX->usriX_acct_expires = u3->usri3_acct_expires;
221 uX->usriX_max_storage = u3->usri3_max_storage;
222 uX->usriX_units_per_week= u3->usri3_units_per_week;
223 uX->usriX_logon_hours = u3->usri3_logon_hours;
224 uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
225 uX->usriX_num_logons = u3->usri3_num_logons;
226 uX->usriX_logon_server = u3->usri3_logon_server;
227 uX->usriX_country_code = u3->usri3_country_code;
228 uX->usriX_code_page = u3->usri3_code_page;
229 uX->usriX_user_id = u3->usri3_user_id;
230 uX->usriX_primary_group_id = u3->usri3_primary_group_id;
231 uX->usriX_profile = u3->usri3_profile;
232 uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
233 uX->usriX_password_expired = u3->usri3_password_expired;
234 break;
235 case 1003:
236 u1003 = (struct USER_INFO_1003 *)buffer;
237 uX->usriX_password = u1003->usri1003_password;
238 break;
239 case 1006:
240 u1006 = (struct USER_INFO_1006 *)buffer;
241 uX->usriX_home_dir = u1006->usri1006_home_dir;
242 break;
243 case 1007:
244 u1007 = (struct USER_INFO_1007 *)buffer;
245 uX->usriX_comment = u1007->usri1007_comment;
246 break;
247 case 1009:
248 u1009 = (struct USER_INFO_1009 *)buffer;
249 uX->usriX_script_path = u1009->usri1009_script_path;
250 break;
251 case 1011:
252 u1011 = (struct USER_INFO_1011 *)buffer;
253 uX->usriX_full_name = u1011->usri1011_full_name;
254 break;
255 case 1012:
256 u1012 = (struct USER_INFO_1012 *)buffer;
257 uX->usriX_usr_comment = u1012->usri1012_usr_comment;
258 break;
259 case 1014:
260 u1014 = (struct USER_INFO_1014 *)buffer;
261 uX->usriX_workstations = u1014->usri1014_workstations;
262 break;
263 case 1024:
264 u1024 = (struct USER_INFO_1024 *)buffer;
265 uX->usriX_country_code = u1024->usri1024_country_code;
266 break;
267 case 1051:
268 u1051 = (struct USER_INFO_1051 *)buffer;
269 uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
270 break;
271 case 1052:
272 u1052 = (struct USER_INFO_1052 *)buffer;
273 uX->usriX_profile = u1052->usri1052_profile;
274 break;
275 case 1053:
276 u1053 = (struct USER_INFO_1053 *)buffer;
277 uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
278 break;
279 case 4:
280 default:
281 return NT_STATUS_INVALID_INFO_CLASS;
284 return NT_STATUS_OK;
287 /****************************************************************
288 ****************************************************************/
290 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
291 struct rpc_pipe_client *pipe_cli,
292 DATA_BLOB *session_key,
293 struct policy_handle *user_handle,
294 struct USER_INFO_X *uX)
296 union samr_UserInfo user_info;
297 struct samr_UserInfo21 info21;
298 NTSTATUS status;
300 if (!uX) {
301 return NT_STATUS_INVALID_PARAMETER;
304 convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
306 ZERO_STRUCT(user_info);
308 if (uX->usriX_password) {
310 user_info.info25.info = info21;
312 init_samr_CryptPasswordEx(uX->usriX_password,
313 session_key,
314 &user_info.info25.password);
316 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
317 user_handle,
319 &user_info);
321 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
323 user_info.info23.info = info21;
325 init_samr_CryptPassword(uX->usriX_password,
326 session_key,
327 &user_info.info23.password);
329 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
330 user_handle,
332 &user_info);
334 } else {
336 user_info.info21 = info21;
338 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
339 user_handle,
341 &user_info);
344 return status;
347 /****************************************************************
348 ****************************************************************/
350 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
351 struct NetUserAdd *r)
353 struct rpc_pipe_client *pipe_cli = NULL;
354 NTSTATUS status;
355 WERROR werr;
356 struct policy_handle connect_handle, domain_handle, user_handle;
357 struct lsa_String lsa_account_name;
358 struct dom_sid2 *domain_sid = NULL;
359 union samr_UserInfo *user_info = NULL;
360 struct samr_PwInfo pw_info;
361 uint32_t access_granted = 0;
362 uint32_t rid = 0;
363 struct USER_INFO_X uX;
365 ZERO_STRUCT(connect_handle);
366 ZERO_STRUCT(domain_handle);
367 ZERO_STRUCT(user_handle);
369 if (!r->in.buffer) {
370 return WERR_INVALID_PARAM;
373 switch (r->in.level) {
374 case 1:
375 break;
376 case 2:
377 case 3:
378 case 4:
379 default:
380 werr = WERR_NOT_SUPPORTED;
381 goto done;
384 werr = libnetapi_open_pipe(ctx, r->in.server_name,
385 &ndr_table_samr.syntax_id,
386 &pipe_cli);
387 if (!W_ERROR_IS_OK(werr)) {
388 goto done;
391 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
392 if (!NT_STATUS_IS_OK(status)) {
393 werr = ntstatus_to_werror(status);
394 goto done;
397 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
398 SAMR_ACCESS_ENUM_DOMAINS |
399 SAMR_ACCESS_LOOKUP_DOMAIN,
400 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
401 SAMR_DOMAIN_ACCESS_CREATE_USER |
402 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
403 &connect_handle,
404 &domain_handle,
405 &domain_sid);
406 if (!W_ERROR_IS_OK(werr)) {
407 goto done;
410 init_lsa_String(&lsa_account_name, uX.usriX_name);
412 status = rpccli_samr_CreateUser2(pipe_cli, ctx,
413 &domain_handle,
414 &lsa_account_name,
415 ACB_NORMAL,
416 SEC_STD_WRITE_DAC |
417 SEC_STD_DELETE |
418 SAMR_USER_ACCESS_SET_PASSWORD |
419 SAMR_USER_ACCESS_SET_ATTRIBUTES |
420 SAMR_USER_ACCESS_GET_ATTRIBUTES,
421 &user_handle,
422 &access_granted,
423 &rid);
424 if (!NT_STATUS_IS_OK(status)) {
425 werr = ntstatus_to_werror(status);
426 goto done;
429 status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
430 &user_handle,
432 &user_info);
433 if (!NT_STATUS_IS_OK(status)) {
434 werr = ntstatus_to_werror(status);
435 goto done;
438 if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
439 werr = WERR_INVALID_PARAM;
440 goto done;
443 status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
444 &user_handle,
445 &pw_info);
446 if (!NT_STATUS_IS_OK(status)) {
447 werr = ntstatus_to_werror(status);
448 goto done;
451 uX.usriX_flags |= ACB_NORMAL;
453 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
454 &pipe_cli->auth->user_session_key,
455 &user_handle,
456 &uX);
457 if (!NT_STATUS_IS_OK(status)) {
458 werr = ntstatus_to_werror(status);
459 goto failed;
462 werr = WERR_OK;
463 goto done;
465 failed:
466 rpccli_samr_DeleteUser(pipe_cli, ctx,
467 &user_handle);
469 done:
470 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
471 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
474 if (ctx->disable_policy_handle_cache) {
475 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
476 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
479 return werr;
482 /****************************************************************
483 ****************************************************************/
485 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
486 struct NetUserAdd *r)
488 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
491 /****************************************************************
492 ****************************************************************/
494 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
495 struct NetUserDel *r)
497 struct rpc_pipe_client *pipe_cli = NULL;
498 NTSTATUS status;
499 WERROR werr;
500 struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
501 struct lsa_String lsa_account_name;
502 struct samr_Ids user_rids, name_types;
503 struct dom_sid2 *domain_sid = NULL;
504 struct dom_sid2 user_sid;
506 ZERO_STRUCT(connect_handle);
507 ZERO_STRUCT(builtin_handle);
508 ZERO_STRUCT(domain_handle);
509 ZERO_STRUCT(user_handle);
511 werr = libnetapi_open_pipe(ctx, r->in.server_name,
512 &ndr_table_samr.syntax_id,
513 &pipe_cli);
515 if (!W_ERROR_IS_OK(werr)) {
516 goto done;
519 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
520 SAMR_ACCESS_ENUM_DOMAINS |
521 SAMR_ACCESS_LOOKUP_DOMAIN,
522 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
523 &connect_handle,
524 &domain_handle,
525 &domain_sid);
526 if (!W_ERROR_IS_OK(werr)) {
527 goto done;
530 status = rpccli_samr_OpenDomain(pipe_cli, ctx,
531 &connect_handle,
532 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
533 CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
534 &builtin_handle);
535 if (!NT_STATUS_IS_OK(status)) {
536 werr = ntstatus_to_werror(status);
537 goto done;
540 init_lsa_String(&lsa_account_name, r->in.user_name);
542 status = rpccli_samr_LookupNames(pipe_cli, ctx,
543 &domain_handle,
545 &lsa_account_name,
546 &user_rids,
547 &name_types);
548 if (!NT_STATUS_IS_OK(status)) {
549 werr = ntstatus_to_werror(status);
550 goto done;
553 status = rpccli_samr_OpenUser(pipe_cli, ctx,
554 &domain_handle,
555 SEC_STD_DELETE,
556 user_rids.ids[0],
557 &user_handle);
558 if (!NT_STATUS_IS_OK(status)) {
559 werr = ntstatus_to_werror(status);
560 goto done;
563 sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
565 status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
566 &builtin_handle,
567 &user_sid);
568 if (!NT_STATUS_IS_OK(status)) {
569 werr = ntstatus_to_werror(status);
570 goto done;
573 status = rpccli_samr_DeleteUser(pipe_cli, ctx,
574 &user_handle);
575 if (!NT_STATUS_IS_OK(status)) {
576 werr = ntstatus_to_werror(status);
577 goto done;
580 werr = WERR_OK;
582 done:
583 if (is_valid_policy_hnd(&user_handle)) {
584 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
587 if (ctx->disable_policy_handle_cache) {
588 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
589 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
590 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
593 return werr;
596 /****************************************************************
597 ****************************************************************/
599 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
600 struct NetUserDel *r)
602 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
605 /****************************************************************
606 ****************************************************************/
608 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
609 struct rpc_pipe_client *pipe_cli,
610 struct policy_handle *domain_handle,
611 struct policy_handle *builtin_handle,
612 const char *user_name,
613 const struct dom_sid *domain_sid,
614 uint32_t rid,
615 uint32_t level,
616 struct samr_UserInfo21 **info21,
617 struct sec_desc_buf **sec_desc,
618 uint32_t *auth_flag_p)
620 NTSTATUS status;
622 struct policy_handle user_handle;
623 union samr_UserInfo *user_info = NULL;
624 struct samr_RidWithAttributeArray *rid_array = NULL;
625 uint32_t access_mask = SEC_STD_READ_CONTROL |
626 SAMR_USER_ACCESS_GET_ATTRIBUTES |
627 SAMR_USER_ACCESS_GET_NAME_ETC;
629 ZERO_STRUCT(user_handle);
631 switch (level) {
632 case 0:
633 break;
634 case 1:
635 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
636 SAMR_USER_ACCESS_GET_GROUPS;
637 break;
638 case 2:
639 case 3:
640 case 4:
641 case 11:
642 access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
643 SAMR_USER_ACCESS_GET_GROUPS |
644 SAMR_USER_ACCESS_GET_LOCALE;
645 break;
646 case 10:
647 case 20:
648 case 23:
649 break;
650 default:
651 return NT_STATUS_INVALID_LEVEL;
654 if (level == 0) {
655 return NT_STATUS_OK;
658 status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
659 domain_handle,
660 access_mask,
661 rid,
662 &user_handle);
663 if (!NT_STATUS_IS_OK(status)) {
664 goto done;
667 status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
668 &user_handle,
670 &user_info);
671 if (!NT_STATUS_IS_OK(status)) {
672 goto done;
675 status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
676 &user_handle,
677 SECINFO_DACL,
678 sec_desc);
679 if (!NT_STATUS_IS_OK(status)) {
680 goto done;
683 if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
685 struct lsa_SidArray sid_array;
686 struct samr_Ids alias_rids;
687 int i;
688 uint32_t auth_flag = 0;
689 struct dom_sid sid;
691 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
692 &user_handle,
693 &rid_array);
694 if (!NT_STATUS_IS_OK(status)) {
695 goto done;
698 sid_array.num_sids = rid_array->count + 1;
699 sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
700 sid_array.num_sids);
701 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
703 for (i=0; i<rid_array->count; i++) {
704 sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
705 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
706 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
709 sid_compose(&sid, domain_sid, rid);
710 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
711 NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
713 status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
714 builtin_handle,
715 &sid_array,
716 &alias_rids);
717 if (!NT_STATUS_IS_OK(status)) {
718 goto done;
721 for (i=0; i<alias_rids.count; i++) {
722 switch (alias_rids.ids[i]) {
723 case 550: /* Print Operators */
724 auth_flag |= AF_OP_PRINT;
725 break;
726 case 549: /* Server Operators */
727 auth_flag |= AF_OP_SERVER;
728 break;
729 case 548: /* Account Operators */
730 auth_flag |= AF_OP_ACCOUNTS;
731 break;
732 default:
733 break;
737 if (auth_flag_p) {
738 *auth_flag_p = auth_flag;
742 *info21 = &user_info->info21;
744 done:
745 if (is_valid_policy_hnd(&user_handle)) {
746 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
749 return status;
752 /****************************************************************
753 ****************************************************************/
755 static uint32_t samr_rid_to_priv_level(uint32_t rid)
757 switch (rid) {
758 case DOMAIN_RID_ADMINISTRATOR:
759 return USER_PRIV_ADMIN;
760 case DOMAIN_RID_GUEST:
761 return USER_PRIV_GUEST;
762 default:
763 return USER_PRIV_USER;
767 /****************************************************************
768 ****************************************************************/
770 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
772 uint32_t fl = UF_SCRIPT; /* god knows why */
774 fl |= ds_acb2uf(acb);
776 return fl;
779 /****************************************************************
780 ****************************************************************/
782 static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
783 const struct samr_UserInfo21 *i21,
784 struct USER_INFO_1 *i)
786 ZERO_STRUCTP(i);
787 i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
788 NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
789 i->usri1_password = NULL;
790 i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
791 i->usri1_priv = samr_rid_to_priv_level(i21->rid);
792 i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
793 i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
794 i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
795 i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
797 return NT_STATUS_OK;
800 /****************************************************************
801 ****************************************************************/
803 static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
804 const struct samr_UserInfo21 *i21,
805 uint32_t auth_flag,
806 struct USER_INFO_2 *i)
808 ZERO_STRUCTP(i);
810 i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
811 NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
812 i->usri2_password = NULL;
813 i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
814 i->usri2_priv = samr_rid_to_priv_level(i21->rid);
815 i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
816 i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
817 i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
818 i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
819 i->usri2_auth_flags = auth_flag;
820 i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
821 i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
822 i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
823 i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
824 i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
825 i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
826 i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
827 i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
828 i->usri2_units_per_week = i21->logon_hours.units_per_week;
829 i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
830 i->usri2_bad_pw_count = i21->bad_password_count;
831 i->usri2_num_logons = i21->logon_count;
832 i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
833 i->usri2_country_code = i21->country_code;
834 i->usri2_code_page = i21->code_page;
836 return NT_STATUS_OK;
839 /****************************************************************
840 ****************************************************************/
842 static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
843 const struct samr_UserInfo21 *i21,
844 uint32_t auth_flag,
845 struct USER_INFO_3 *i)
847 ZERO_STRUCTP(i);
849 i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
850 NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
851 i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
852 i->usri3_priv = samr_rid_to_priv_level(i21->rid);
853 i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
854 i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
855 i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
856 i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
857 i->usri3_auth_flags = auth_flag;
858 i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
859 i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
860 i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
861 i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
862 i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
863 i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
864 i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
865 i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
866 i->usri3_units_per_week = i21->logon_hours.units_per_week;
867 i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
868 i->usri3_bad_pw_count = i21->bad_password_count;
869 i->usri3_num_logons = i21->logon_count;
870 i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
871 i->usri3_country_code = i21->country_code;
872 i->usri3_code_page = i21->code_page;
873 i->usri3_user_id = i21->rid;
874 i->usri3_primary_group_id = i21->primary_gid;
875 i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
876 i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
877 i->usri3_password_expired = i21->password_expired;
879 return NT_STATUS_OK;
882 /****************************************************************
883 ****************************************************************/
885 static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
886 const struct samr_UserInfo21 *i21,
887 uint32_t auth_flag,
888 struct dom_sid *domain_sid,
889 struct USER_INFO_4 *i)
891 struct dom_sid sid;
893 ZERO_STRUCTP(i);
895 i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
896 NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
897 i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
898 i->usri4_password = NULL;
899 i->usri4_priv = samr_rid_to_priv_level(i21->rid);
900 i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
901 i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
902 i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
903 i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
904 i->usri4_auth_flags = auth_flag;
905 i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
906 i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
907 i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
908 i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
909 i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
910 i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
911 i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
912 i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
913 i->usri4_units_per_week = i21->logon_hours.units_per_week;
914 i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
915 i->usri4_bad_pw_count = i21->bad_password_count;
916 i->usri4_num_logons = i21->logon_count;
917 i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
918 i->usri4_country_code = i21->country_code;
919 i->usri4_code_page = i21->code_page;
920 if (!sid_compose(&sid, domain_sid, i21->rid)) {
921 return NT_STATUS_NO_MEMORY;
923 i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
924 i->usri4_primary_group_id = i21->primary_gid;
925 i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
926 i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
927 i->usri4_password_expired = i21->password_expired;
929 return NT_STATUS_OK;
932 /****************************************************************
933 ****************************************************************/
935 static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
936 const struct samr_UserInfo21 *i21,
937 struct USER_INFO_10 *i)
939 ZERO_STRUCTP(i);
941 i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
942 NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
943 i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
944 i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
945 i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
947 return NT_STATUS_OK;
950 /****************************************************************
951 ****************************************************************/
953 static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
954 const struct samr_UserInfo21 *i21,
955 uint32_t auth_flag,
956 struct USER_INFO_11 *i)
958 ZERO_STRUCTP(i);
960 i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
961 NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
962 i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
963 i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
964 i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
965 i->usri11_priv = samr_rid_to_priv_level(i21->rid);
966 i->usri11_auth_flags = auth_flag;
967 i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
968 i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
969 i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
970 i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
971 i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
972 i->usri11_bad_pw_count = i21->bad_password_count;
973 i->usri11_num_logons = i21->logon_count;
974 i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
975 i->usri11_country_code = i21->country_code;
976 i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
977 i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
978 i->usri11_units_per_week = i21->logon_hours.units_per_week;
979 i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
980 i->usri11_code_page = i21->code_page;
982 return NT_STATUS_OK;
985 /****************************************************************
986 ****************************************************************/
988 static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
989 const struct samr_UserInfo21 *i21,
990 struct USER_INFO_20 *i)
992 ZERO_STRUCTP(i);
994 i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
995 NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
996 i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
997 i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
998 i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
999 i->usri20_user_id = i21->rid;
1001 return NT_STATUS_OK;
1004 /****************************************************************
1005 ****************************************************************/
1007 static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1008 const struct samr_UserInfo21 *i21,
1009 struct dom_sid *domain_sid,
1010 struct USER_INFO_23 *i)
1012 struct dom_sid sid;
1014 ZERO_STRUCTP(i);
1016 i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1017 NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1018 i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1019 i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1020 i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1021 if (!sid_compose(&sid, domain_sid, i21->rid)) {
1022 return NT_STATUS_NO_MEMORY;
1024 i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
1026 return NT_STATUS_OK;
1029 /****************************************************************
1030 ****************************************************************/
1032 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1033 struct rpc_pipe_client *pipe_cli,
1034 struct dom_sid *domain_sid,
1035 struct policy_handle *domain_handle,
1036 struct policy_handle *builtin_handle,
1037 const char *user_name,
1038 uint32_t rid,
1039 uint32_t level,
1040 uint8_t **buffer,
1041 uint32_t *num_entries)
1043 NTSTATUS status;
1045 struct samr_UserInfo21 *info21 = NULL;
1046 struct sec_desc_buf *sec_desc = NULL;
1047 uint32_t auth_flag = 0;
1049 struct USER_INFO_0 info0;
1050 struct USER_INFO_1 info1;
1051 struct USER_INFO_2 info2;
1052 struct USER_INFO_3 info3;
1053 struct USER_INFO_4 info4;
1054 struct USER_INFO_10 info10;
1055 struct USER_INFO_11 info11;
1056 struct USER_INFO_20 info20;
1057 struct USER_INFO_23 info23;
1059 switch (level) {
1060 case 0:
1061 case 1:
1062 case 2:
1063 case 3:
1064 case 4:
1065 case 10:
1066 case 11:
1067 case 20:
1068 case 23:
1069 break;
1070 default:
1071 return NT_STATUS_INVALID_LEVEL;
1074 if (level == 0) {
1075 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1076 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1078 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1079 (struct USER_INFO_0 **)buffer, num_entries);
1081 return NT_STATUS_OK;
1084 status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1085 domain_handle,
1086 builtin_handle,
1087 user_name,
1088 domain_sid,
1089 rid,
1090 level,
1091 &info21,
1092 &sec_desc,
1093 &auth_flag);
1095 if (!NT_STATUS_IS_OK(status)) {
1096 goto done;
1099 switch (level) {
1100 case 0:
1101 /* already returned above */
1102 break;
1103 case 1:
1104 status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1105 NT_STATUS_NOT_OK_RETURN(status);
1107 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1108 (struct USER_INFO_1 **)buffer, num_entries);
1110 break;
1111 case 2:
1112 status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1113 NT_STATUS_NOT_OK_RETURN(status);
1115 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1116 (struct USER_INFO_2 **)buffer, num_entries);
1118 break;
1119 case 3:
1120 status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1121 NT_STATUS_NOT_OK_RETURN(status);
1123 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1124 (struct USER_INFO_3 **)buffer, num_entries);
1126 break;
1127 case 4:
1128 status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1129 NT_STATUS_NOT_OK_RETURN(status);
1131 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1132 (struct USER_INFO_4 **)buffer, num_entries);
1134 break;
1135 case 10:
1136 status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1137 NT_STATUS_NOT_OK_RETURN(status);
1139 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1140 (struct USER_INFO_10 **)buffer, num_entries);
1142 break;
1143 case 11:
1144 status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1145 NT_STATUS_NOT_OK_RETURN(status);
1147 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1148 (struct USER_INFO_11 **)buffer, num_entries);
1150 break;
1151 case 20:
1152 status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1153 NT_STATUS_NOT_OK_RETURN(status);
1155 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1156 (struct USER_INFO_20 **)buffer, num_entries);
1158 break;
1159 case 23:
1160 status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1161 NT_STATUS_NOT_OK_RETURN(status);
1163 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1164 (struct USER_INFO_23 **)buffer, num_entries);
1165 break;
1166 default:
1167 return NT_STATUS_INVALID_LEVEL;
1170 done:
1171 return status;
1174 /****************************************************************
1175 ****************************************************************/
1177 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1178 struct NetUserEnum *r)
1180 struct rpc_pipe_client *pipe_cli = NULL;
1181 struct policy_handle connect_handle;
1182 struct dom_sid2 *domain_sid = NULL;
1183 struct policy_handle domain_handle, builtin_handle;
1184 struct samr_SamArray *sam = NULL;
1185 uint32_t filter = ACB_NORMAL;
1186 int i;
1187 uint32_t entries_read = 0;
1189 NTSTATUS status = NT_STATUS_OK;
1190 WERROR werr;
1192 ZERO_STRUCT(connect_handle);
1193 ZERO_STRUCT(domain_handle);
1194 ZERO_STRUCT(builtin_handle);
1196 if (!r->out.buffer) {
1197 return WERR_INVALID_PARAM;
1200 *r->out.buffer = NULL;
1201 *r->out.entries_read = 0;
1203 switch (r->in.level) {
1204 case 0:
1205 case 1:
1206 case 2:
1207 case 3:
1208 case 4:
1209 case 10:
1210 case 11:
1211 case 20:
1212 case 23:
1213 break;
1214 default:
1215 return WERR_UNKNOWN_LEVEL;
1218 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1219 &ndr_table_samr.syntax_id,
1220 &pipe_cli);
1221 if (!W_ERROR_IS_OK(werr)) {
1222 goto done;
1225 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1226 SAMR_ACCESS_ENUM_DOMAINS |
1227 SAMR_ACCESS_LOOKUP_DOMAIN,
1228 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1229 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1230 &connect_handle,
1231 &builtin_handle);
1232 if (!W_ERROR_IS_OK(werr)) {
1233 goto done;
1236 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1237 SAMR_ACCESS_ENUM_DOMAINS |
1238 SAMR_ACCESS_LOOKUP_DOMAIN,
1239 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1240 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1241 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1242 &connect_handle,
1243 &domain_handle,
1244 &domain_sid);
1245 if (!W_ERROR_IS_OK(werr)) {
1246 goto done;
1249 switch (r->in.filter) {
1250 case FILTER_NORMAL_ACCOUNT:
1251 filter = ACB_NORMAL;
1252 break;
1253 case FILTER_TEMP_DUPLICATE_ACCOUNT:
1254 filter = ACB_TEMPDUP;
1255 break;
1256 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1257 filter = ACB_DOMTRUST;
1258 break;
1259 case FILTER_WORKSTATION_TRUST_ACCOUNT:
1260 filter = ACB_WSTRUST;
1261 break;
1262 case FILTER_SERVER_TRUST_ACCOUNT:
1263 filter = ACB_SVRTRUST;
1264 break;
1265 default:
1266 break;
1269 status = rpccli_samr_EnumDomainUsers(pipe_cli,
1270 ctx,
1271 &domain_handle,
1272 r->in.resume_handle,
1273 filter,
1274 &sam,
1275 r->in.prefmaxlen,
1276 &entries_read);
1277 werr = ntstatus_to_werror(status);
1278 if (NT_STATUS_IS_ERR(status)) {
1279 goto done;
1282 for (i=0; i < sam->count; i++) {
1284 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1285 domain_sid,
1286 &domain_handle,
1287 &builtin_handle,
1288 sam->entries[i].name.string,
1289 sam->entries[i].idx,
1290 r->in.level,
1291 r->out.buffer,
1292 r->out.entries_read);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 werr = ntstatus_to_werror(status);
1295 goto done;
1299 done:
1300 /* if last query */
1301 if (NT_STATUS_IS_OK(status) ||
1302 NT_STATUS_IS_ERR(status)) {
1304 if (ctx->disable_policy_handle_cache) {
1305 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1306 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1307 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1311 return werr;
1314 /****************************************************************
1315 ****************************************************************/
1317 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1318 struct NetUserEnum *r)
1320 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1323 /****************************************************************
1324 ****************************************************************/
1326 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1327 struct samr_DispInfoGeneral *info,
1328 uint32_t *entries_read,
1329 void **buffer)
1331 struct NET_DISPLAY_USER *user = NULL;
1332 int i;
1334 user = TALLOC_ZERO_ARRAY(mem_ctx,
1335 struct NET_DISPLAY_USER,
1336 info->count);
1337 W_ERROR_HAVE_NO_MEMORY(user);
1339 for (i = 0; i < info->count; i++) {
1340 user[i].usri1_name = talloc_strdup(mem_ctx,
1341 info->entries[i].account_name.string);
1342 user[i].usri1_comment = talloc_strdup(mem_ctx,
1343 info->entries[i].description.string);
1344 user[i].usri1_flags =
1345 info->entries[i].acct_flags;
1346 user[i].usri1_full_name = talloc_strdup(mem_ctx,
1347 info->entries[i].full_name.string);
1348 user[i].usri1_user_id =
1349 info->entries[i].rid;
1350 user[i].usri1_next_index =
1351 info->entries[i].idx;
1353 if (!user[i].usri1_name) {
1354 return WERR_NOMEM;
1358 *buffer = talloc_memdup(mem_ctx, user,
1359 sizeof(struct NET_DISPLAY_USER) * info->count);
1360 W_ERROR_HAVE_NO_MEMORY(*buffer);
1362 *entries_read = info->count;
1364 return WERR_OK;
1367 /****************************************************************
1368 ****************************************************************/
1370 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1371 struct samr_DispInfoFull *info,
1372 uint32_t *entries_read,
1373 void **buffer)
1375 struct NET_DISPLAY_MACHINE *machine = NULL;
1376 int i;
1378 machine = TALLOC_ZERO_ARRAY(mem_ctx,
1379 struct NET_DISPLAY_MACHINE,
1380 info->count);
1381 W_ERROR_HAVE_NO_MEMORY(machine);
1383 for (i = 0; i < info->count; i++) {
1384 machine[i].usri2_name = talloc_strdup(mem_ctx,
1385 info->entries[i].account_name.string);
1386 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1387 info->entries[i].description.string);
1388 machine[i].usri2_flags =
1389 info->entries[i].acct_flags;
1390 machine[i].usri2_user_id =
1391 info->entries[i].rid;
1392 machine[i].usri2_next_index =
1393 info->entries[i].idx;
1395 if (!machine[i].usri2_name) {
1396 return WERR_NOMEM;
1400 *buffer = talloc_memdup(mem_ctx, machine,
1401 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1402 W_ERROR_HAVE_NO_MEMORY(*buffer);
1404 *entries_read = info->count;
1406 return WERR_OK;
1409 /****************************************************************
1410 ****************************************************************/
1412 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1413 struct samr_DispInfoFullGroups *info,
1414 uint32_t *entries_read,
1415 void **buffer)
1417 struct NET_DISPLAY_GROUP *group = NULL;
1418 int i;
1420 group = TALLOC_ZERO_ARRAY(mem_ctx,
1421 struct NET_DISPLAY_GROUP,
1422 info->count);
1423 W_ERROR_HAVE_NO_MEMORY(group);
1425 for (i = 0; i < info->count; i++) {
1426 group[i].grpi3_name = talloc_strdup(mem_ctx,
1427 info->entries[i].account_name.string);
1428 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1429 info->entries[i].description.string);
1430 group[i].grpi3_group_id =
1431 info->entries[i].rid;
1432 group[i].grpi3_attributes =
1433 info->entries[i].acct_flags;
1434 group[i].grpi3_next_index =
1435 info->entries[i].idx;
1437 if (!group[i].grpi3_name) {
1438 return WERR_NOMEM;
1442 *buffer = talloc_memdup(mem_ctx, group,
1443 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1444 W_ERROR_HAVE_NO_MEMORY(*buffer);
1446 *entries_read = info->count;
1448 return WERR_OK;
1452 /****************************************************************
1453 ****************************************************************/
1455 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1456 union samr_DispInfo *info,
1457 uint32_t level,
1458 uint32_t *entries_read,
1459 void **buffer)
1461 switch (level) {
1462 case 1:
1463 return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1464 &info->info1,
1465 entries_read,
1466 buffer);
1467 case 2:
1468 return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1469 &info->info2,
1470 entries_read,
1471 buffer);
1472 case 3:
1473 return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1474 &info->info3,
1475 entries_read,
1476 buffer);
1477 default:
1478 break;
1481 return WERR_UNKNOWN_LEVEL;
1484 /****************************************************************
1485 ****************************************************************/
1487 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1488 struct NetQueryDisplayInformation *r)
1490 struct rpc_pipe_client *pipe_cli = NULL;
1491 struct policy_handle connect_handle;
1492 struct dom_sid2 *domain_sid = NULL;
1493 struct policy_handle domain_handle;
1494 union samr_DispInfo info;
1496 uint32_t total_size = 0;
1497 uint32_t returned_size = 0;
1499 NTSTATUS status = NT_STATUS_OK;
1500 WERROR werr;
1501 WERROR werr_tmp;
1503 *r->out.entries_read = 0;
1505 ZERO_STRUCT(connect_handle);
1506 ZERO_STRUCT(domain_handle);
1508 switch (r->in.level) {
1509 case 1:
1510 case 2:
1511 case 3:
1512 break;
1513 default:
1514 return WERR_UNKNOWN_LEVEL;
1517 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1518 &ndr_table_samr.syntax_id,
1519 &pipe_cli);
1520 if (!W_ERROR_IS_OK(werr)) {
1521 goto done;
1524 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1525 SAMR_ACCESS_ENUM_DOMAINS |
1526 SAMR_ACCESS_LOOKUP_DOMAIN,
1527 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1528 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1529 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1530 &connect_handle,
1531 &domain_handle,
1532 &domain_sid);
1533 if (!W_ERROR_IS_OK(werr)) {
1534 goto done;
1537 status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1538 ctx,
1539 &domain_handle,
1540 r->in.level,
1541 r->in.idx,
1542 r->in.entries_requested,
1543 r->in.prefmaxlen,
1544 &total_size,
1545 &returned_size,
1546 &info);
1547 werr = ntstatus_to_werror(status);
1548 if (NT_STATUS_IS_ERR(status)) {
1549 goto done;
1552 werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1553 r->in.level,
1554 r->out.entries_read,
1555 r->out.buffer);
1556 if (!W_ERROR_IS_OK(werr_tmp)) {
1557 werr = werr_tmp;
1559 done:
1560 /* if last query */
1561 if (NT_STATUS_IS_OK(status) ||
1562 NT_STATUS_IS_ERR(status)) {
1564 if (ctx->disable_policy_handle_cache) {
1565 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1566 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1570 return werr;
1574 /****************************************************************
1575 ****************************************************************/
1578 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1579 struct NetQueryDisplayInformation *r)
1581 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1584 /****************************************************************
1585 ****************************************************************/
1587 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1588 struct NetUserChangePassword *r)
1590 return WERR_NOT_SUPPORTED;
1593 /****************************************************************
1594 ****************************************************************/
1596 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1597 struct NetUserChangePassword *r)
1599 return WERR_NOT_SUPPORTED;
1602 /****************************************************************
1603 ****************************************************************/
1605 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1606 struct NetUserGetInfo *r)
1608 struct rpc_pipe_client *pipe_cli = NULL;
1609 NTSTATUS status;
1610 WERROR werr;
1612 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1613 struct lsa_String lsa_account_name;
1614 struct dom_sid2 *domain_sid = NULL;
1615 struct samr_Ids user_rids, name_types;
1616 uint32_t num_entries = 0;
1618 ZERO_STRUCT(connect_handle);
1619 ZERO_STRUCT(domain_handle);
1620 ZERO_STRUCT(builtin_handle);
1621 ZERO_STRUCT(user_handle);
1623 if (!r->out.buffer) {
1624 return WERR_INVALID_PARAM;
1627 switch (r->in.level) {
1628 case 0:
1629 case 1:
1630 case 2:
1631 case 3:
1632 case 4:
1633 case 10:
1634 case 11:
1635 case 20:
1636 case 23:
1637 break;
1638 default:
1639 werr = WERR_UNKNOWN_LEVEL;
1640 goto done;
1643 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1644 &ndr_table_samr.syntax_id,
1645 &pipe_cli);
1646 if (!W_ERROR_IS_OK(werr)) {
1647 goto done;
1650 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1651 SAMR_ACCESS_ENUM_DOMAINS |
1652 SAMR_ACCESS_LOOKUP_DOMAIN,
1653 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1654 &connect_handle,
1655 &domain_handle,
1656 &domain_sid);
1657 if (!W_ERROR_IS_OK(werr)) {
1658 goto done;
1661 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1662 SAMR_ACCESS_ENUM_DOMAINS |
1663 SAMR_ACCESS_LOOKUP_DOMAIN,
1664 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1665 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1666 &connect_handle,
1667 &builtin_handle);
1668 if (!W_ERROR_IS_OK(werr)) {
1669 goto done;
1672 init_lsa_String(&lsa_account_name, r->in.user_name);
1674 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1675 &domain_handle,
1677 &lsa_account_name,
1678 &user_rids,
1679 &name_types);
1680 if (!NT_STATUS_IS_OK(status)) {
1681 werr = ntstatus_to_werror(status);
1682 goto done;
1685 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1686 domain_sid,
1687 &domain_handle,
1688 &builtin_handle,
1689 r->in.user_name,
1690 user_rids.ids[0],
1691 r->in.level,
1692 r->out.buffer,
1693 &num_entries);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 werr = ntstatus_to_werror(status);
1696 goto done;
1699 done:
1700 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1701 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1704 if (ctx->disable_policy_handle_cache) {
1705 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1706 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1709 return werr;
1712 /****************************************************************
1713 ****************************************************************/
1715 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1716 struct NetUserGetInfo *r)
1718 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1721 /****************************************************************
1722 ****************************************************************/
1724 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1725 struct NetUserSetInfo *r)
1727 struct rpc_pipe_client *pipe_cli = NULL;
1728 NTSTATUS status;
1729 WERROR werr;
1731 struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1732 struct lsa_String lsa_account_name;
1733 struct dom_sid2 *domain_sid = NULL;
1734 struct samr_Ids user_rids, name_types;
1735 uint32_t user_mask = 0;
1737 struct USER_INFO_X uX;
1739 ZERO_STRUCT(connect_handle);
1740 ZERO_STRUCT(domain_handle);
1741 ZERO_STRUCT(builtin_handle);
1742 ZERO_STRUCT(user_handle);
1744 if (!r->in.buffer) {
1745 return WERR_INVALID_PARAM;
1748 switch (r->in.level) {
1749 case 0:
1750 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1751 break;
1752 case 1003:
1753 user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1754 break;
1755 case 1006:
1756 case 1007:
1757 case 1009:
1758 case 1011:
1759 case 1014:
1760 case 1052:
1761 case 1053:
1762 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1763 break;
1764 case 1012:
1765 case 1024:
1766 user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1767 case 1051:
1768 user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1769 SAMR_USER_ACCESS_GET_GROUPS;
1770 break;
1771 case 3:
1772 user_mask = STD_RIGHT_READ_CONTROL_ACCESS |
1773 STD_RIGHT_WRITE_DAC_ACCESS |
1774 SAMR_USER_ACCESS_GET_GROUPS |
1775 SAMR_USER_ACCESS_SET_PASSWORD |
1776 SAMR_USER_ACCESS_SET_ATTRIBUTES |
1777 SAMR_USER_ACCESS_GET_ATTRIBUTES |
1778 SAMR_USER_ACCESS_SET_LOC_COM;
1779 break;
1780 case 1:
1781 case 2:
1782 case 4:
1783 case 21:
1784 case 22:
1785 case 1005:
1786 case 1008:
1787 case 1010:
1788 case 1017:
1789 case 1020:
1790 werr = WERR_NOT_SUPPORTED;
1791 goto done;
1792 default:
1793 werr = WERR_UNKNOWN_LEVEL;
1794 goto done;
1797 werr = libnetapi_open_pipe(ctx, r->in.server_name,
1798 &ndr_table_samr.syntax_id,
1799 &pipe_cli);
1800 if (!W_ERROR_IS_OK(werr)) {
1801 goto done;
1804 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1805 SAMR_ACCESS_ENUM_DOMAINS |
1806 SAMR_ACCESS_LOOKUP_DOMAIN,
1807 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1808 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1809 &connect_handle,
1810 &domain_handle,
1811 &domain_sid);
1812 if (!W_ERROR_IS_OK(werr)) {
1813 goto done;
1816 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1817 SAMR_ACCESS_ENUM_DOMAINS |
1818 SAMR_ACCESS_LOOKUP_DOMAIN,
1819 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1820 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1821 &connect_handle,
1822 &builtin_handle);
1823 if (!W_ERROR_IS_OK(werr)) {
1824 goto done;
1827 init_lsa_String(&lsa_account_name, r->in.user_name);
1829 status = rpccli_samr_LookupNames(pipe_cli, ctx,
1830 &domain_handle,
1832 &lsa_account_name,
1833 &user_rids,
1834 &name_types);
1835 if (!NT_STATUS_IS_OK(status)) {
1836 werr = ntstatus_to_werror(status);
1837 goto done;
1840 status = rpccli_samr_OpenUser(pipe_cli, ctx,
1841 &domain_handle,
1842 user_mask,
1843 user_rids.ids[0],
1844 &user_handle);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 werr = ntstatus_to_werror(status);
1847 goto done;
1850 status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 werr = ntstatus_to_werror(status);
1853 goto done;
1856 status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1857 &pipe_cli->auth->user_session_key,
1858 &user_handle,
1859 &uX);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 werr = ntstatus_to_werror(status);
1862 goto done;
1865 werr = WERR_OK;
1867 done:
1868 if (is_valid_policy_hnd(&user_handle) && pipe_cli) {
1869 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1872 if (ctx->disable_policy_handle_cache) {
1873 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1874 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1875 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1878 return werr;
1881 /****************************************************************
1882 ****************************************************************/
1884 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1885 struct NetUserSetInfo *r)
1887 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1890 /****************************************************************
1891 ****************************************************************/
1893 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1894 struct rpc_pipe_client *pipe_cli,
1895 struct policy_handle *domain_handle,
1896 struct samr_DomInfo1 *info1,
1897 struct samr_DomInfo3 *info3,
1898 struct samr_DomInfo5 *info5,
1899 struct samr_DomInfo6 *info6,
1900 struct samr_DomInfo7 *info7,
1901 struct samr_DomInfo12 *info12)
1903 NTSTATUS status;
1904 union samr_DomainInfo *dom_info = NULL;
1906 if (info1) {
1907 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1908 domain_handle,
1910 &dom_info);
1911 NT_STATUS_NOT_OK_RETURN(status);
1913 *info1 = dom_info->info1;
1916 if (info3) {
1917 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1918 domain_handle,
1920 &dom_info);
1921 NT_STATUS_NOT_OK_RETURN(status);
1923 *info3 = dom_info->info3;
1926 if (info5) {
1927 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1928 domain_handle,
1930 &dom_info);
1931 NT_STATUS_NOT_OK_RETURN(status);
1933 *info5 = dom_info->info5;
1936 if (info6) {
1937 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1938 domain_handle,
1940 &dom_info);
1941 NT_STATUS_NOT_OK_RETURN(status);
1943 *info6 = dom_info->info6;
1946 if (info7) {
1947 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1948 domain_handle,
1950 &dom_info);
1951 NT_STATUS_NOT_OK_RETURN(status);
1953 *info7 = dom_info->info7;
1956 if (info12) {
1957 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1958 domain_handle,
1960 &dom_info);
1961 NT_STATUS_NOT_OK_RETURN(status);
1963 *info12 = dom_info->info12;
1966 return NT_STATUS_OK;
1969 /****************************************************************
1970 ****************************************************************/
1972 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1973 struct rpc_pipe_client *pipe_cli,
1974 struct policy_handle *domain_handle,
1975 struct USER_MODALS_INFO_0 *info0)
1977 NTSTATUS status;
1978 struct samr_DomInfo1 dom_info1;
1979 struct samr_DomInfo3 dom_info3;
1981 ZERO_STRUCTP(info0);
1983 status = query_USER_MODALS_INFO_rpc(mem_ctx,
1984 pipe_cli,
1985 domain_handle,
1986 &dom_info1,
1987 &dom_info3,
1988 NULL,
1989 NULL,
1990 NULL,
1991 NULL);
1992 NT_STATUS_NOT_OK_RETURN(status);
1994 info0->usrmod0_min_passwd_len =
1995 dom_info1.min_password_length;
1996 info0->usrmod0_max_passwd_age =
1997 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1998 info0->usrmod0_min_passwd_age =
1999 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2000 info0->usrmod0_password_hist_len =
2001 dom_info1.password_history_length;
2003 info0->usrmod0_force_logoff =
2004 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2006 return NT_STATUS_OK;
2009 /****************************************************************
2010 ****************************************************************/
2012 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2013 struct rpc_pipe_client *pipe_cli,
2014 struct policy_handle *domain_handle,
2015 struct USER_MODALS_INFO_1 *info1)
2017 NTSTATUS status;
2018 struct samr_DomInfo6 dom_info6;
2019 struct samr_DomInfo7 dom_info7;
2021 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2022 pipe_cli,
2023 domain_handle,
2024 NULL,
2025 NULL,
2026 NULL,
2027 &dom_info6,
2028 &dom_info7,
2029 NULL);
2030 NT_STATUS_NOT_OK_RETURN(status);
2032 info1->usrmod1_primary =
2033 talloc_strdup(mem_ctx, dom_info6.primary.string);
2035 info1->usrmod1_role = dom_info7.role;
2037 return NT_STATUS_OK;
2040 /****************************************************************
2041 ****************************************************************/
2043 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2044 struct rpc_pipe_client *pipe_cli,
2045 struct policy_handle *domain_handle,
2046 struct dom_sid *domain_sid,
2047 struct USER_MODALS_INFO_2 *info2)
2049 NTSTATUS status;
2050 struct samr_DomInfo5 dom_info5;
2052 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2053 pipe_cli,
2054 domain_handle,
2055 NULL,
2056 NULL,
2057 &dom_info5,
2058 NULL,
2059 NULL,
2060 NULL);
2061 NT_STATUS_NOT_OK_RETURN(status);
2063 info2->usrmod2_domain_name =
2064 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2065 info2->usrmod2_domain_id =
2066 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
2068 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2069 NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2071 return NT_STATUS_OK;
2074 /****************************************************************
2075 ****************************************************************/
2077 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2078 struct rpc_pipe_client *pipe_cli,
2079 struct policy_handle *domain_handle,
2080 struct USER_MODALS_INFO_3 *info3)
2082 NTSTATUS status;
2083 struct samr_DomInfo12 dom_info12;
2085 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2086 pipe_cli,
2087 domain_handle,
2088 NULL,
2089 NULL,
2090 NULL,
2091 NULL,
2092 NULL,
2093 &dom_info12);
2094 NT_STATUS_NOT_OK_RETURN(status);
2096 info3->usrmod3_lockout_duration =
2097 nt_time_to_unix_abs(&dom_info12.lockout_duration);
2098 info3->usrmod3_lockout_observation_window =
2099 nt_time_to_unix_abs(&dom_info12.lockout_window);
2100 info3->usrmod3_lockout_threshold =
2101 dom_info12.lockout_threshold;
2103 return NT_STATUS_OK;
2106 /****************************************************************
2107 ****************************************************************/
2109 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2110 struct rpc_pipe_client *pipe_cli,
2111 uint32_t level,
2112 struct policy_handle *domain_handle,
2113 struct dom_sid *domain_sid,
2114 uint8_t **buffer)
2116 NTSTATUS status;
2118 struct USER_MODALS_INFO_0 info0;
2119 struct USER_MODALS_INFO_1 info1;
2120 struct USER_MODALS_INFO_2 info2;
2121 struct USER_MODALS_INFO_3 info3;
2123 if (!buffer) {
2124 return ERROR_INSUFFICIENT_BUFFER;
2127 switch (level) {
2128 case 0:
2129 status = query_USER_MODALS_INFO_0(mem_ctx,
2130 pipe_cli,
2131 domain_handle,
2132 &info0);
2133 NT_STATUS_NOT_OK_RETURN(status);
2135 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2136 sizeof(info0));
2137 break;
2139 case 1:
2140 status = query_USER_MODALS_INFO_1(mem_ctx,
2141 pipe_cli,
2142 domain_handle,
2143 &info1);
2144 NT_STATUS_NOT_OK_RETURN(status);
2146 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2147 sizeof(info1));
2148 break;
2149 case 2:
2150 status = query_USER_MODALS_INFO_2(mem_ctx,
2151 pipe_cli,
2152 domain_handle,
2153 domain_sid,
2154 &info2);
2155 NT_STATUS_NOT_OK_RETURN(status);
2157 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2158 sizeof(info2));
2159 break;
2160 case 3:
2161 status = query_USER_MODALS_INFO_3(mem_ctx,
2162 pipe_cli,
2163 domain_handle,
2164 &info3);
2165 NT_STATUS_NOT_OK_RETURN(status);
2167 *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2168 sizeof(info3));
2169 break;
2170 default:
2171 break;
2174 NT_STATUS_HAVE_NO_MEMORY(*buffer);
2176 return NT_STATUS_OK;
2179 /****************************************************************
2180 ****************************************************************/
2182 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2183 struct NetUserModalsGet *r)
2185 struct rpc_pipe_client *pipe_cli = NULL;
2186 NTSTATUS status;
2187 WERROR werr;
2189 struct policy_handle connect_handle, domain_handle;
2190 struct dom_sid2 *domain_sid = NULL;
2191 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2193 ZERO_STRUCT(connect_handle);
2194 ZERO_STRUCT(domain_handle);
2196 if (!r->out.buffer) {
2197 return WERR_INVALID_PARAM;
2200 switch (r->in.level) {
2201 case 0:
2202 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2203 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2204 break;
2205 case 1:
2206 case 2:
2207 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2208 break;
2209 case 3:
2210 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2211 break;
2212 default:
2213 werr = WERR_UNKNOWN_LEVEL;
2214 goto done;
2217 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2218 &ndr_table_samr.syntax_id,
2219 &pipe_cli);
2220 if (!W_ERROR_IS_OK(werr)) {
2221 goto done;
2224 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2225 SAMR_ACCESS_ENUM_DOMAINS |
2226 SAMR_ACCESS_LOOKUP_DOMAIN,
2227 access_mask,
2228 &connect_handle,
2229 &domain_handle,
2230 &domain_sid);
2231 if (!W_ERROR_IS_OK(werr)) {
2232 goto done;
2235 /* 0: 1 + 3 */
2236 /* 1: 6 + 7 */
2237 /* 2: 5 */
2238 /* 3: 12 (DomainInfo2) */
2240 status = query_USER_MODALS_INFO_to_buffer(ctx,
2241 pipe_cli,
2242 r->in.level,
2243 &domain_handle,
2244 domain_sid,
2245 r->out.buffer);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 werr = ntstatus_to_werror(status);
2248 goto done;
2251 done:
2252 if (ctx->disable_policy_handle_cache) {
2253 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2254 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2257 return werr;
2260 /****************************************************************
2261 ****************************************************************/
2263 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2264 struct NetUserModalsGet *r)
2266 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2269 /****************************************************************
2270 ****************************************************************/
2272 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2273 struct rpc_pipe_client *pipe_cli,
2274 struct policy_handle *domain_handle,
2275 struct samr_DomInfo1 *info1,
2276 struct samr_DomInfo3 *info3,
2277 struct samr_DomInfo12 *info12)
2279 NTSTATUS status;
2280 union samr_DomainInfo dom_info;
2282 if (info1) {
2284 ZERO_STRUCT(dom_info);
2286 dom_info.info1 = *info1;
2288 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2289 domain_handle,
2291 &dom_info);
2292 NT_STATUS_NOT_OK_RETURN(status);
2295 if (info3) {
2297 ZERO_STRUCT(dom_info);
2299 dom_info.info3 = *info3;
2301 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2302 domain_handle,
2304 &dom_info);
2306 NT_STATUS_NOT_OK_RETURN(status);
2309 if (info12) {
2311 ZERO_STRUCT(dom_info);
2313 dom_info.info12 = *info12;
2315 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
2316 domain_handle,
2318 &dom_info);
2320 NT_STATUS_NOT_OK_RETURN(status);
2323 return NT_STATUS_OK;
2326 /****************************************************************
2327 ****************************************************************/
2329 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2330 struct rpc_pipe_client *pipe_cli,
2331 struct policy_handle *domain_handle,
2332 struct USER_MODALS_INFO_0 *info0)
2334 NTSTATUS status;
2335 struct samr_DomInfo1 dom_info_1;
2336 struct samr_DomInfo3 dom_info_3;
2338 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2339 pipe_cli,
2340 domain_handle,
2341 &dom_info_1,
2342 &dom_info_3,
2343 NULL,
2344 NULL,
2345 NULL,
2346 NULL);
2347 NT_STATUS_NOT_OK_RETURN(status);
2349 dom_info_1.min_password_length =
2350 info0->usrmod0_min_passwd_len;
2351 dom_info_1.password_history_length =
2352 info0->usrmod0_password_hist_len;
2354 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2355 info0->usrmod0_max_passwd_age);
2356 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2357 info0->usrmod0_min_passwd_age);
2359 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2360 info0->usrmod0_force_logoff);
2362 return set_USER_MODALS_INFO_rpc(mem_ctx,
2363 pipe_cli,
2364 domain_handle,
2365 &dom_info_1,
2366 &dom_info_3,
2367 NULL);
2370 /****************************************************************
2371 ****************************************************************/
2373 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2374 struct rpc_pipe_client *pipe_cli,
2375 struct policy_handle *domain_handle,
2376 struct USER_MODALS_INFO_3 *info3)
2378 NTSTATUS status;
2379 struct samr_DomInfo12 dom_info_12;
2381 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2382 pipe_cli,
2383 domain_handle,
2384 NULL,
2385 NULL,
2386 NULL,
2387 NULL,
2388 NULL,
2389 &dom_info_12);
2390 NT_STATUS_NOT_OK_RETURN(status);
2392 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2393 info3->usrmod3_lockout_duration);
2394 unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2395 info3->usrmod3_lockout_observation_window);
2396 dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2398 return set_USER_MODALS_INFO_rpc(mem_ctx,
2399 pipe_cli,
2400 domain_handle,
2401 NULL,
2402 NULL,
2403 &dom_info_12);
2406 /****************************************************************
2407 ****************************************************************/
2409 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2410 struct rpc_pipe_client *pipe_cli,
2411 struct policy_handle *domain_handle,
2412 struct USER_MODALS_INFO_1001 *info1001)
2414 NTSTATUS status;
2415 struct samr_DomInfo1 dom_info_1;
2417 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2418 pipe_cli,
2419 domain_handle,
2420 &dom_info_1,
2421 NULL,
2422 NULL,
2423 NULL,
2424 NULL,
2425 NULL);
2426 NT_STATUS_NOT_OK_RETURN(status);
2428 dom_info_1.min_password_length =
2429 info1001->usrmod1001_min_passwd_len;
2431 return set_USER_MODALS_INFO_rpc(mem_ctx,
2432 pipe_cli,
2433 domain_handle,
2434 &dom_info_1,
2435 NULL,
2436 NULL);
2439 /****************************************************************
2440 ****************************************************************/
2442 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2443 struct rpc_pipe_client *pipe_cli,
2444 struct policy_handle *domain_handle,
2445 struct USER_MODALS_INFO_1002 *info1002)
2447 NTSTATUS status;
2448 struct samr_DomInfo1 dom_info_1;
2450 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2451 pipe_cli,
2452 domain_handle,
2453 &dom_info_1,
2454 NULL,
2455 NULL,
2456 NULL,
2457 NULL,
2458 NULL);
2459 NT_STATUS_NOT_OK_RETURN(status);
2461 unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2462 info1002->usrmod1002_max_passwd_age);
2464 return set_USER_MODALS_INFO_rpc(mem_ctx,
2465 pipe_cli,
2466 domain_handle,
2467 &dom_info_1,
2468 NULL,
2469 NULL);
2472 /****************************************************************
2473 ****************************************************************/
2475 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2476 struct rpc_pipe_client *pipe_cli,
2477 struct policy_handle *domain_handle,
2478 struct USER_MODALS_INFO_1003 *info1003)
2480 NTSTATUS status;
2481 struct samr_DomInfo1 dom_info_1;
2483 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2484 pipe_cli,
2485 domain_handle,
2486 &dom_info_1,
2487 NULL,
2488 NULL,
2489 NULL,
2490 NULL,
2491 NULL);
2492 NT_STATUS_NOT_OK_RETURN(status);
2494 unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2495 info1003->usrmod1003_min_passwd_age);
2497 return set_USER_MODALS_INFO_rpc(mem_ctx,
2498 pipe_cli,
2499 domain_handle,
2500 &dom_info_1,
2501 NULL,
2502 NULL);
2505 /****************************************************************
2506 ****************************************************************/
2508 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2509 struct rpc_pipe_client *pipe_cli,
2510 struct policy_handle *domain_handle,
2511 struct USER_MODALS_INFO_1004 *info1004)
2513 NTSTATUS status;
2514 struct samr_DomInfo3 dom_info_3;
2516 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2517 pipe_cli,
2518 domain_handle,
2519 NULL,
2520 &dom_info_3,
2521 NULL,
2522 NULL,
2523 NULL,
2524 NULL);
2525 NT_STATUS_NOT_OK_RETURN(status);
2527 unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2528 info1004->usrmod1004_force_logoff);
2530 return set_USER_MODALS_INFO_rpc(mem_ctx,
2531 pipe_cli,
2532 domain_handle,
2533 NULL,
2534 &dom_info_3,
2535 NULL);
2538 /****************************************************************
2539 ****************************************************************/
2541 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2542 struct rpc_pipe_client *pipe_cli,
2543 struct policy_handle *domain_handle,
2544 struct USER_MODALS_INFO_1005 *info1005)
2546 NTSTATUS status;
2547 struct samr_DomInfo1 dom_info_1;
2549 status = query_USER_MODALS_INFO_rpc(mem_ctx,
2550 pipe_cli,
2551 domain_handle,
2552 &dom_info_1,
2553 NULL,
2554 NULL,
2555 NULL,
2556 NULL,
2557 NULL);
2558 NT_STATUS_NOT_OK_RETURN(status);
2560 dom_info_1.password_history_length =
2561 info1005->usrmod1005_password_hist_len;
2563 return set_USER_MODALS_INFO_rpc(mem_ctx,
2564 pipe_cli,
2565 domain_handle,
2566 &dom_info_1,
2567 NULL,
2568 NULL);
2571 /****************************************************************
2572 ****************************************************************/
2574 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2575 struct rpc_pipe_client *pipe_cli,
2576 uint32_t level,
2577 struct policy_handle *domain_handle,
2578 struct dom_sid *domain_sid,
2579 uint8_t *buffer)
2581 struct USER_MODALS_INFO_0 *info0;
2582 struct USER_MODALS_INFO_3 *info3;
2583 struct USER_MODALS_INFO_1001 *info1001;
2584 struct USER_MODALS_INFO_1002 *info1002;
2585 struct USER_MODALS_INFO_1003 *info1003;
2586 struct USER_MODALS_INFO_1004 *info1004;
2587 struct USER_MODALS_INFO_1005 *info1005;
2589 if (!buffer) {
2590 return ERROR_INSUFFICIENT_BUFFER;
2593 switch (level) {
2594 case 0:
2595 info0 = (struct USER_MODALS_INFO_0 *)buffer;
2596 return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2597 pipe_cli,
2598 domain_handle,
2599 info0);
2600 case 3:
2601 info3 = (struct USER_MODALS_INFO_3 *)buffer;
2602 return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2603 pipe_cli,
2604 domain_handle,
2605 info3);
2606 case 1001:
2607 info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2608 return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2609 pipe_cli,
2610 domain_handle,
2611 info1001);
2612 case 1002:
2613 info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2614 return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2615 pipe_cli,
2616 domain_handle,
2617 info1002);
2618 case 1003:
2619 info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2620 return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2621 pipe_cli,
2622 domain_handle,
2623 info1003);
2624 case 1004:
2625 info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2626 return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2627 pipe_cli,
2628 domain_handle,
2629 info1004);
2630 case 1005:
2631 info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2632 return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2633 pipe_cli,
2634 domain_handle,
2635 info1005);
2637 default:
2638 break;
2641 return NT_STATUS_OK;
2644 /****************************************************************
2645 ****************************************************************/
2647 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2648 struct NetUserModalsSet *r)
2650 struct rpc_pipe_client *pipe_cli = NULL;
2651 NTSTATUS status;
2652 WERROR werr;
2654 struct policy_handle connect_handle, domain_handle;
2655 struct dom_sid2 *domain_sid = NULL;
2656 uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2658 ZERO_STRUCT(connect_handle);
2659 ZERO_STRUCT(domain_handle);
2661 if (!r->in.buffer) {
2662 return WERR_INVALID_PARAM;
2665 switch (r->in.level) {
2666 case 0:
2667 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2668 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2669 SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2670 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2671 break;
2672 case 3:
2673 case 1001:
2674 case 1002:
2675 case 1003:
2676 case 1005:
2677 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2678 SAMR_DOMAIN_ACCESS_SET_INFO_1;
2679 break;
2680 case 1004:
2681 access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2682 SAMR_DOMAIN_ACCESS_SET_INFO_2;
2683 break;
2684 case 1:
2685 case 2:
2686 case 1006:
2687 case 1007:
2688 werr = WERR_NOT_SUPPORTED;
2689 break;
2690 default:
2691 werr = WERR_UNKNOWN_LEVEL;
2692 goto done;
2695 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2696 &ndr_table_samr.syntax_id,
2697 &pipe_cli);
2698 if (!W_ERROR_IS_OK(werr)) {
2699 goto done;
2702 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2703 SAMR_ACCESS_ENUM_DOMAINS |
2704 SAMR_ACCESS_LOOKUP_DOMAIN,
2705 access_mask,
2706 &connect_handle,
2707 &domain_handle,
2708 &domain_sid);
2709 if (!W_ERROR_IS_OK(werr)) {
2710 goto done;
2713 status = set_USER_MODALS_INFO_buffer(ctx,
2714 pipe_cli,
2715 r->in.level,
2716 &domain_handle,
2717 domain_sid,
2718 r->in.buffer);
2719 if (!NT_STATUS_IS_OK(status)) {
2720 werr = ntstatus_to_werror(status);
2721 goto done;
2724 done:
2725 if (ctx->disable_policy_handle_cache) {
2726 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2727 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2730 return werr;
2733 /****************************************************************
2734 ****************************************************************/
2736 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2737 struct NetUserModalsSet *r)
2739 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2742 /****************************************************************
2743 ****************************************************************/
2745 NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2746 uint32_t level,
2747 const char *group_name,
2748 uint32_t attributes,
2749 uint8_t **buffer,
2750 uint32_t *num_entries)
2752 struct GROUP_USERS_INFO_0 u0;
2753 struct GROUP_USERS_INFO_1 u1;
2755 switch (level) {
2756 case 0:
2757 if (group_name) {
2758 u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2759 NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2760 } else {
2761 u0.grui0_name = NULL;
2764 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2765 (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2766 break;
2767 case 1:
2768 if (group_name) {
2769 u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2770 NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2771 } else {
2772 u1.grui1_name = NULL;
2775 u1.grui1_attributes = attributes;
2777 ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2778 (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2779 break;
2780 default:
2781 return NT_STATUS_INVALID_INFO_CLASS;
2784 return NT_STATUS_OK;
2787 /****************************************************************
2788 ****************************************************************/
2790 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2791 struct NetUserGetGroups *r)
2793 struct rpc_pipe_client *pipe_cli = NULL;
2794 struct policy_handle connect_handle, domain_handle, user_handle;
2795 struct lsa_String lsa_account_name;
2796 struct dom_sid2 *domain_sid = NULL;
2797 struct samr_Ids user_rids, name_types;
2798 struct samr_RidWithAttributeArray *rid_array = NULL;
2799 struct lsa_Strings names;
2800 struct samr_Ids types;
2801 uint32_t *rids = NULL;
2803 int i;
2804 uint32_t entries_read = 0;
2806 NTSTATUS status = NT_STATUS_OK;
2807 WERROR werr;
2809 ZERO_STRUCT(connect_handle);
2810 ZERO_STRUCT(domain_handle);
2812 if (!r->out.buffer) {
2813 return WERR_INVALID_PARAM;
2816 *r->out.buffer = NULL;
2817 *r->out.entries_read = 0;
2818 *r->out.total_entries = 0;
2820 switch (r->in.level) {
2821 case 0:
2822 case 1:
2823 break;
2824 default:
2825 return WERR_UNKNOWN_LEVEL;
2828 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2829 &ndr_table_samr.syntax_id,
2830 &pipe_cli);
2831 if (!W_ERROR_IS_OK(werr)) {
2832 goto done;
2835 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2836 SAMR_ACCESS_ENUM_DOMAINS |
2837 SAMR_ACCESS_LOOKUP_DOMAIN,
2838 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2839 &connect_handle,
2840 &domain_handle,
2841 &domain_sid);
2842 if (!W_ERROR_IS_OK(werr)) {
2843 goto done;
2846 init_lsa_String(&lsa_account_name, r->in.user_name);
2848 status = rpccli_samr_LookupNames(pipe_cli, ctx,
2849 &domain_handle,
2851 &lsa_account_name,
2852 &user_rids,
2853 &name_types);
2854 if (!NT_STATUS_IS_OK(status)) {
2855 werr = ntstatus_to_werror(status);
2856 goto done;
2859 status = rpccli_samr_OpenUser(pipe_cli, ctx,
2860 &domain_handle,
2861 SAMR_USER_ACCESS_GET_GROUPS,
2862 user_rids.ids[0],
2863 &user_handle);
2864 if (!NT_STATUS_IS_OK(status)) {
2865 werr = ntstatus_to_werror(status);
2866 goto done;
2869 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2870 &user_handle,
2871 &rid_array);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 werr = ntstatus_to_werror(status);
2874 goto done;
2877 rids = talloc_array(ctx, uint32_t, rid_array->count);
2878 if (!rids) {
2879 werr = WERR_NOMEM;
2880 goto done;
2883 for (i=0; i < rid_array->count; i++) {
2884 rids[i] = rid_array->rids[i].rid;
2887 status = rpccli_samr_LookupRids(pipe_cli, ctx,
2888 &domain_handle,
2889 rid_array->count,
2890 rids,
2891 &names,
2892 &types);
2893 if (!NT_STATUS_IS_OK(status) &&
2894 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
2895 werr = ntstatus_to_werror(status);
2896 goto done;
2899 for (i=0; i < names.count; i++) {
2900 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2901 r->in.level,
2902 names.names[i].string,
2903 rid_array->rids[i].attributes,
2904 r->out.buffer,
2905 &entries_read);
2906 if (!NT_STATUS_IS_OK(status)) {
2907 werr = ntstatus_to_werror(status);
2908 goto done;
2912 *r->out.entries_read = entries_read;
2913 *r->out.total_entries = entries_read;
2915 done:
2916 if (ctx->disable_policy_handle_cache) {
2917 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2918 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2921 return werr;
2924 /****************************************************************
2925 ****************************************************************/
2927 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2928 struct NetUserGetGroups *r)
2930 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
2933 /****************************************************************
2934 ****************************************************************/
2936 WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
2937 struct NetUserSetGroups *r)
2939 struct rpc_pipe_client *pipe_cli = NULL;
2940 struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
2941 struct lsa_String lsa_account_name;
2942 struct dom_sid2 *domain_sid = NULL;
2943 struct samr_Ids user_rids, name_types;
2944 struct samr_Ids group_rids;
2945 struct samr_RidWithAttributeArray *rid_array = NULL;
2946 struct lsa_String *lsa_names = NULL;
2948 uint32_t *add_rids = NULL;
2949 uint32_t *del_rids = NULL;
2950 size_t num_add_rids = 0;
2951 size_t num_del_rids = 0;
2953 uint32_t *member_rids = NULL;
2954 size_t num_member_rids = 0;
2956 struct GROUP_USERS_INFO_0 *i0 = NULL;
2957 struct GROUP_USERS_INFO_1 *i1 = NULL;
2959 int i, k;
2961 NTSTATUS status = NT_STATUS_OK;
2962 WERROR werr;
2964 ZERO_STRUCT(connect_handle);
2965 ZERO_STRUCT(domain_handle);
2967 if (!r->in.buffer) {
2968 return WERR_INVALID_PARAM;
2971 switch (r->in.level) {
2972 case 0:
2973 case 1:
2974 break;
2975 default:
2976 return WERR_UNKNOWN_LEVEL;
2979 werr = libnetapi_open_pipe(ctx, r->in.server_name,
2980 &ndr_table_samr.syntax_id,
2981 &pipe_cli);
2982 if (!W_ERROR_IS_OK(werr)) {
2983 goto done;
2986 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2987 SAMR_ACCESS_ENUM_DOMAINS |
2988 SAMR_ACCESS_LOOKUP_DOMAIN,
2989 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2990 &connect_handle,
2991 &domain_handle,
2992 &domain_sid);
2993 if (!W_ERROR_IS_OK(werr)) {
2994 goto done;
2997 init_lsa_String(&lsa_account_name, r->in.user_name);
2999 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3000 &domain_handle,
3002 &lsa_account_name,
3003 &user_rids,
3004 &name_types);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 werr = ntstatus_to_werror(status);
3007 goto done;
3010 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3011 &domain_handle,
3012 SAMR_USER_ACCESS_GET_GROUPS,
3013 user_rids.ids[0],
3014 &user_handle);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 werr = ntstatus_to_werror(status);
3017 goto done;
3020 switch (r->in.level) {
3021 case 0:
3022 i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3023 break;
3024 case 1:
3025 i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3026 break;
3029 lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3030 if (!lsa_names) {
3031 werr = WERR_NOMEM;
3032 goto done;
3035 for (i=0; i < r->in.num_entries; i++) {
3037 switch (r->in.level) {
3038 case 0:
3039 init_lsa_String(&lsa_names[i], i0->grui0_name);
3040 i0++;
3041 break;
3042 case 1:
3043 init_lsa_String(&lsa_names[i], i1->grui1_name);
3044 i1++;
3045 break;
3049 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3050 &domain_handle,
3051 r->in.num_entries,
3052 lsa_names,
3053 &group_rids,
3054 &name_types);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 werr = ntstatus_to_werror(status);
3057 goto done;
3060 member_rids = group_rids.ids;
3061 num_member_rids = group_rids.count;
3063 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3064 &user_handle,
3065 &rid_array);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 werr = ntstatus_to_werror(status);
3068 goto done;
3071 /* add list */
3073 for (i=0; i < r->in.num_entries; i++) {
3074 bool already_member = false;
3075 for (k=0; k < rid_array->count; k++) {
3076 if (member_rids[i] == rid_array->rids[k].rid) {
3077 already_member = true;
3078 break;
3081 if (!already_member) {
3082 if (!add_rid_to_array_unique(ctx,
3083 member_rids[i],
3084 &add_rids, &num_add_rids)) {
3085 werr = WERR_GENERAL_FAILURE;
3086 goto done;
3091 /* del list */
3093 for (k=0; k < rid_array->count; k++) {
3094 bool keep_member = false;
3095 for (i=0; i < r->in.num_entries; i++) {
3096 if (member_rids[i] == rid_array->rids[k].rid) {
3097 keep_member = true;
3098 break;
3101 if (!keep_member) {
3102 if (!add_rid_to_array_unique(ctx,
3103 rid_array->rids[k].rid,
3104 &del_rids, &num_del_rids)) {
3105 werr = WERR_GENERAL_FAILURE;
3106 goto done;
3111 /* add list */
3113 for (i=0; i < num_add_rids; i++) {
3114 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3115 &domain_handle,
3116 SAMR_GROUP_ACCESS_ADD_MEMBER,
3117 add_rids[i],
3118 &group_handle);
3119 if (!NT_STATUS_IS_OK(status)) {
3120 werr = ntstatus_to_werror(status);
3121 goto done;
3124 status = rpccli_samr_AddGroupMember(pipe_cli, ctx,
3125 &group_handle,
3126 user_rids.ids[0],
3127 7 /* ? */);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 werr = ntstatus_to_werror(status);
3130 goto done;
3133 if (is_valid_policy_hnd(&group_handle)) {
3134 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3138 /* del list */
3140 for (i=0; i < num_del_rids; i++) {
3141 status = rpccli_samr_OpenGroup(pipe_cli, ctx,
3142 &domain_handle,
3143 SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3144 del_rids[i],
3145 &group_handle);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 werr = ntstatus_to_werror(status);
3148 goto done;
3151 status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx,
3152 &group_handle,
3153 user_rids.ids[0]);
3154 if (!NT_STATUS_IS_OK(status)) {
3155 werr = ntstatus_to_werror(status);
3156 goto done;
3159 if (is_valid_policy_hnd(&group_handle)) {
3160 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3164 werr = WERR_OK;
3166 done:
3167 if (is_valid_policy_hnd(&group_handle)) {
3168 rpccli_samr_Close(pipe_cli, ctx, &group_handle);
3171 if (ctx->disable_policy_handle_cache) {
3172 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3173 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3176 return werr;
3179 /****************************************************************
3180 ****************************************************************/
3182 WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3183 struct NetUserSetGroups *r)
3185 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3188 /****************************************************************
3189 ****************************************************************/
3191 static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3192 uint32_t level,
3193 const char *group_name,
3194 uint8_t **buffer,
3195 uint32_t *num_entries)
3197 struct LOCALGROUP_USERS_INFO_0 u0;
3199 switch (level) {
3200 case 0:
3201 u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3202 NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3204 ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3205 (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3206 break;
3207 default:
3208 return NT_STATUS_INVALID_INFO_CLASS;
3211 return NT_STATUS_OK;
3214 /****************************************************************
3215 ****************************************************************/
3217 WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3218 struct NetUserGetLocalGroups *r)
3220 struct rpc_pipe_client *pipe_cli = NULL;
3221 struct policy_handle connect_handle, domain_handle, user_handle,
3222 builtin_handle;
3223 struct lsa_String lsa_account_name;
3224 struct dom_sid2 *domain_sid = NULL;
3225 struct samr_Ids user_rids, name_types;
3226 struct samr_RidWithAttributeArray *rid_array = NULL;
3227 struct lsa_Strings names;
3228 struct samr_Ids types;
3229 uint32_t *rids = NULL;
3230 size_t num_rids = 0;
3231 struct dom_sid user_sid;
3232 struct lsa_SidArray sid_array;
3233 struct samr_Ids domain_rids;
3234 struct samr_Ids builtin_rids;
3236 int i;
3237 uint32_t entries_read = 0;
3239 NTSTATUS status = NT_STATUS_OK;
3240 WERROR werr;
3242 ZERO_STRUCT(connect_handle);
3243 ZERO_STRUCT(domain_handle);
3245 if (!r->out.buffer) {
3246 return WERR_INVALID_PARAM;
3249 *r->out.buffer = NULL;
3250 *r->out.entries_read = 0;
3251 *r->out.total_entries = 0;
3253 switch (r->in.level) {
3254 case 0:
3255 case 1:
3256 break;
3257 default:
3258 return WERR_UNKNOWN_LEVEL;
3261 werr = libnetapi_open_pipe(ctx, r->in.server_name,
3262 &ndr_table_samr.syntax_id,
3263 &pipe_cli);
3264 if (!W_ERROR_IS_OK(werr)) {
3265 goto done;
3268 werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3269 SAMR_ACCESS_ENUM_DOMAINS |
3270 SAMR_ACCESS_LOOKUP_DOMAIN,
3271 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3272 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3273 &connect_handle,
3274 &domain_handle,
3275 &domain_sid);
3276 if (!W_ERROR_IS_OK(werr)) {
3277 goto done;
3280 werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3281 SAMR_ACCESS_ENUM_DOMAINS |
3282 SAMR_ACCESS_LOOKUP_DOMAIN,
3283 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3284 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3285 &connect_handle,
3286 &builtin_handle);
3287 if (!W_ERROR_IS_OK(werr)) {
3288 goto done;
3291 init_lsa_String(&lsa_account_name, r->in.user_name);
3293 status = rpccli_samr_LookupNames(pipe_cli, ctx,
3294 &domain_handle,
3296 &lsa_account_name,
3297 &user_rids,
3298 &name_types);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 werr = ntstatus_to_werror(status);
3301 goto done;
3304 status = rpccli_samr_OpenUser(pipe_cli, ctx,
3305 &domain_handle,
3306 SAMR_USER_ACCESS_GET_GROUPS,
3307 user_rids.ids[0],
3308 &user_handle);
3309 if (!NT_STATUS_IS_OK(status)) {
3310 werr = ntstatus_to_werror(status);
3311 goto done;
3314 status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
3315 &user_handle,
3316 &rid_array);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 werr = ntstatus_to_werror(status);
3319 goto done;
3322 if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3323 werr = WERR_NOMEM;
3324 goto done;
3327 sid_array.num_sids = rid_array->count + 1;
3328 sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
3329 if (!sid_array.sids) {
3330 werr = WERR_NOMEM;
3331 goto done;
3334 sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid);
3335 if (!sid_array.sids[0].sid) {
3336 werr = WERR_NOMEM;
3337 goto done;
3340 for (i=0; i < rid_array->count; i++) {
3341 struct dom_sid sid;
3343 if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3344 werr = WERR_NOMEM;
3345 goto done;
3348 sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid);
3349 if (!sid_array.sids[i+1].sid) {
3350 werr = WERR_NOMEM;
3351 goto done;
3355 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3356 &domain_handle,
3357 &sid_array,
3358 &domain_rids);
3359 if (!NT_STATUS_IS_OK(status)) {
3360 werr = ntstatus_to_werror(status);
3361 goto done;
3364 for (i=0; i < domain_rids.count; i++) {
3365 if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3366 &rids, &num_rids)) {
3367 werr = WERR_NOMEM;
3368 goto done;
3372 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
3373 &builtin_handle,
3374 &sid_array,
3375 &builtin_rids);
3376 if (!NT_STATUS_IS_OK(status)) {
3377 werr = ntstatus_to_werror(status);
3378 goto done;
3381 for (i=0; i < builtin_rids.count; i++) {
3382 if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3383 &rids, &num_rids)) {
3384 werr = WERR_NOMEM;
3385 goto done;
3389 status = rpccli_samr_LookupRids(pipe_cli, ctx,
3390 &builtin_handle,
3391 num_rids,
3392 rids,
3393 &names,
3394 &types);
3395 if (!NT_STATUS_IS_OK(status)) {
3396 werr = ntstatus_to_werror(status);
3397 goto done;
3400 for (i=0; i < names.count; i++) {
3401 status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3402 r->in.level,
3403 names.names[i].string,
3404 r->out.buffer,
3405 &entries_read);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 werr = ntstatus_to_werror(status);
3408 goto done;
3412 *r->out.entries_read = entries_read;
3413 *r->out.total_entries = entries_read;
3415 done:
3416 if (ctx->disable_policy_handle_cache) {
3417 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3418 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3421 return werr;
3424 /****************************************************************
3425 ****************************************************************/
3427 WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3428 struct NetUserGetLocalGroups *r)
3430 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);