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