1/* 2 Unix SMB/CIFS implementation. 3 4 Winbind rpc backend functions 5 6 Copyright (C) Tim Potter 2000-2001,2003 7 Copyright (C) Andrew Tridgell 2001 8 Copyright (C) Volker Lendecke 2005 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23*/ 24 25#include "includes.h" 26#include "winbindd.h" 27 28#undef DBGC_CLASS 29#define DBGC_CLASS DBGC_WINBIND 30 31 32/* Query display info for a domain. This returns enough information plus a 33 bit extra to give an overview of domain users for the User Manager 34 application. */ 35static NTSTATUS query_user_list(struct winbindd_domain *domain, 36 TALLOC_CTX *mem_ctx, 37 uint32 *num_entries, 38 WINBIND_USERINFO **info) 39{ 40 NTSTATUS result; 41 POLICY_HND dom_pol; 42 unsigned int i, start_idx; 43 uint32 loop_count; 44 struct rpc_pipe_client *cli; 45 46 DEBUG(3,("rpc: query_user_list\n")); 47 48 *num_entries = 0; 49 *info = NULL; 50 51 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 52 if (!NT_STATUS_IS_OK(result)) 53 return result; 54 55 i = start_idx = 0; 56 loop_count = 0; 57 58 do { 59 TALLOC_CTX *ctx2; 60 uint32 num_dom_users, j; 61 uint32 max_entries, max_size; 62 SAM_DISPINFO_CTR ctr; 63 SAM_DISPINFO_1 info1; 64 65 ZERO_STRUCT( ctr ); 66 ZERO_STRUCT( info1 ); 67 ctr.sam.info1 = &info1; 68 69 if (!(ctx2 = talloc_init("winbindd enum_users"))) 70 return NT_STATUS_NO_MEMORY; 71 72 /* this next bit is copied from net_user_list_internal() */ 73 74 get_query_dispinfo_params(loop_count, &max_entries, 75 &max_size); 76 77 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol, 78 &start_idx, 1, 79 &num_dom_users, 80 max_entries, max_size, 81 &ctr); 82 83 loop_count++; 84 85 *num_entries += num_dom_users; 86 87 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO, 88 *num_entries); 89 90 if (!(*info)) { 91 talloc_destroy(ctx2); 92 return NT_STATUS_NO_MEMORY; 93 } 94 95 for (j = 0; j < num_dom_users; i++, j++) { 96 fstring username, fullname; 97 uint32 rid = ctr.sam.info1->sam[j].rid_user; 98 99 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1); 100 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1); 101 102 (*info)[i].acct_name = talloc_strdup(mem_ctx, username ); 103 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname ); 104 (*info)[i].homedir = NULL; 105 (*info)[i].shell = NULL; 106 sid_compose(&(*info)[i].user_sid, &domain->sid, rid); 107 108 /* For the moment we set the primary group for 109 every user to be the Domain Users group. 110 There are serious problems with determining 111 the actual primary group for large domains. 112 This should really be made into a 'winbind 113 force group' smb.conf parameter or 114 something like that. */ 115 116 sid_compose(&(*info)[i].group_sid, &domain->sid, 117 DOMAIN_GROUP_RID_USERS); 118 } 119 120 talloc_destroy(ctx2); 121 122 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 123 124 return result; 125} 126 127/* list all domain groups */ 128static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 129 TALLOC_CTX *mem_ctx, 130 uint32 *num_entries, 131 struct acct_info **info) 132{ 133 POLICY_HND dom_pol; 134 NTSTATUS status; 135 uint32 start = 0; 136 struct rpc_pipe_client *cli; 137 138 *num_entries = 0; 139 *info = NULL; 140 141 DEBUG(3,("rpc: enum_dom_groups\n")); 142 143 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 144 if (!NT_STATUS_IS_OK(status)) 145 return status; 146 147 do { 148 struct acct_info *info2 = NULL; 149 uint32 count = 0; 150 TALLOC_CTX *mem_ctx2; 151 152 mem_ctx2 = talloc_init("enum_dom_groups[rpc]"); 153 154 /* start is updated by this call. */ 155 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol, 156 &start, 157 0xFFFF, /* buffer size? */ 158 &info2, &count); 159 160 if (!NT_STATUS_IS_OK(status) && 161 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 162 talloc_destroy(mem_ctx2); 163 break; 164 } 165 166 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 167 struct acct_info, 168 (*num_entries) + count); 169 if (! *info) { 170 talloc_destroy(mem_ctx2); 171 status = NT_STATUS_NO_MEMORY; 172 break; 173 } 174 175 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2)); 176 (*num_entries) += count; 177 talloc_destroy(mem_ctx2); 178 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); 179 180 return NT_STATUS_OK; 181} 182 183/* List all domain groups */ 184 185static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 186 TALLOC_CTX *mem_ctx, 187 uint32 *num_entries, 188 struct acct_info **info) 189{ 190 POLICY_HND dom_pol; 191 NTSTATUS result; 192 struct rpc_pipe_client *cli; 193 194 *num_entries = 0; 195 *info = NULL; 196 197 DEBUG(3,("rpc: enum_local_groups\n")); 198 199 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 200 if (!NT_STATUS_IS_OK(result)) 201 return result; 202 203 do { 204 struct acct_info *info2 = NULL; 205 uint32 count = 0, start = *num_entries; 206 TALLOC_CTX *mem_ctx2; 207 208 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]"); 209 210 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol, 211 &start, 0xFFFF, &info2, 212 &count); 213 214 if (!NT_STATUS_IS_OK(result) && 215 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 216 { 217 talloc_destroy(mem_ctx2); 218 return result; 219 } 220 221 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 222 struct acct_info, 223 (*num_entries) + count); 224 if (! *info) { 225 talloc_destroy(mem_ctx2); 226 return NT_STATUS_NO_MEMORY; 227 } 228 229 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2)); 230 (*num_entries) += count; 231 talloc_destroy(mem_ctx2); 232 233 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 234 235 return NT_STATUS_OK; 236} 237 238/* convert a single name to a sid in a domain */ 239NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain, 240 TALLOC_CTX *mem_ctx, 241 const char *domain_name, 242 const char *name, 243 DOM_SID *sid, 244 enum lsa_SidType *type) 245{ 246 NTSTATUS result; 247 DOM_SID *sids = NULL; 248 enum lsa_SidType *types = NULL; 249 char *full_name = NULL; 250 struct rpc_pipe_client *cli; 251 POLICY_HND lsa_policy; 252 253 if(name == NULL || *name=='\0') { 254 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name)); 255 full_name = talloc_asprintf(mem_ctx, "%s", domain_name); 256 } else { 257 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name, name)); 258 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name); 259 } 260 if (!full_name) { 261 DEBUG(0, ("talloc_asprintf failed!\n")); 262 return NT_STATUS_NO_MEMORY; 263 } 264 265 ws_name_return( full_name, WB_REPLACE_CHAR ); 266 267 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name )); 268 269 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 270 if (!NT_STATUS_IS_OK(result)) 271 return result; 272 273 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1, 274 (const char**) &full_name, NULL, &sids, &types); 275 276 if (!NT_STATUS_IS_OK(result)) 277 return result; 278 279 /* Return rid and type if lookup successful */ 280 281 sid_copy(sid, &sids[0]); 282 *type = types[0]; 283 284 return NT_STATUS_OK; 285} 286 287/* 288 convert a domain SID to a user or group name 289*/ 290NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, 291 TALLOC_CTX *mem_ctx, 292 const DOM_SID *sid, 293 char **domain_name, 294 char **name, 295 enum lsa_SidType *type) 296{ 297 char **domains; 298 char **names; 299 enum lsa_SidType *types; 300 NTSTATUS result; 301 struct rpc_pipe_client *cli; 302 POLICY_HND lsa_policy; 303 304 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid), 305 domain->name )); 306 307 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 308 if (!NT_STATUS_IS_OK(result)) 309 return result; 310 311 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, 312 1, sid, &domains, &names, &types); 313 if (!NT_STATUS_IS_OK(result)) 314 return result; 315 316 *type = (enum lsa_SidType)types[0]; 317 *domain_name = domains[0]; 318 *name = names[0]; 319 320 ws_name_replace( *name, WB_REPLACE_CHAR ); 321 322 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); 323 return NT_STATUS_OK; 324} 325 326NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, 327 TALLOC_CTX *mem_ctx, 328 const DOM_SID *sid, 329 uint32 *rids, 330 size_t num_rids, 331 char **domain_name, 332 char ***names, 333 enum lsa_SidType **types) 334{ 335 char **domains; 336 NTSTATUS result; 337 struct rpc_pipe_client *cli; 338 POLICY_HND lsa_policy; 339 DOM_SID *sids; 340 size_t i; 341 char **ret_names; 342 343 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name )); 344 345 if (num_rids) { 346 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids); 347 if (sids == NULL) { 348 return NT_STATUS_NO_MEMORY; 349 } 350 } else { 351 sids = NULL; 352 } 353 354 for (i=0; i<num_rids; i++) { 355 if (!sid_compose(&sids[i], sid, rids[i])) { 356 return NT_STATUS_INTERNAL_ERROR; 357 } 358 } 359 360 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 361 if (!NT_STATUS_IS_OK(result)) { 362 return result; 363 } 364 365 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, 366 num_rids, sids, &domains, 367 names, types); 368 if (!NT_STATUS_IS_OK(result) && 369 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 370 return result; 371 } 372 373 ret_names = *names; 374 for (i=0; i<num_rids; i++) { 375 if ((*types)[i] != SID_NAME_UNKNOWN) { 376 ws_name_replace( ret_names[i], WB_REPLACE_CHAR ); 377 *domain_name = domains[i]; 378 } 379 } 380 381 return result; 382} 383 384/* Lookup user information from a rid or username. */ 385static NTSTATUS query_user(struct winbindd_domain *domain, 386 TALLOC_CTX *mem_ctx, 387 const DOM_SID *user_sid, 388 WINBIND_USERINFO *user_info) 389{ 390 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 391 POLICY_HND dom_pol, user_pol; 392 SAM_USERINFO_CTR *ctr; 393 fstring sid_string; 394 uint32 user_rid; 395 NET_USER_INFO_3 *user; 396 struct rpc_pipe_client *cli; 397 398 DEBUG(3,("rpc: query_user sid=%s\n", 399 sid_to_string(sid_string, user_sid))); 400 401 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 402 return NT_STATUS_UNSUCCESSFUL; 403 404 /* try netsamlogon cache first */ 405 406 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 407 { 408 409 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 410 sid_string_static(user_sid))); 411 412 sid_compose(&user_info->user_sid, &domain->sid, user_rid); 413 sid_compose(&user_info->group_sid, &domain->sid, 414 user->group_rid); 415 416 user_info->acct_name = unistr2_tdup(mem_ctx, 417 &user->uni_user_name); 418 user_info->full_name = unistr2_tdup(mem_ctx, 419 &user->uni_full_name); 420 421 user_info->homedir = NULL; 422 user_info->shell = NULL; 423 user_info->primary_gid = (gid_t)-1; 424 425 TALLOC_FREE(user); 426 427 return NT_STATUS_OK; 428 } 429 430 /* no cache; hit the wire */ 431 432 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 433 if (!NT_STATUS_IS_OK(result)) 434 return result; 435 436 /* Get user handle */ 437 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol, 438 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, 439 &user_pol); 440 441 if (!NT_STATUS_IS_OK(result)) 442 return result; 443 444 /* Get user info */ 445 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol, 446 0x15, &ctr); 447 448 rpccli_samr_close(cli, mem_ctx, &user_pol); 449 450 if (!NT_STATUS_IS_OK(result)) 451 return result; 452 453 sid_compose(&user_info->user_sid, &domain->sid, user_rid); 454 sid_compose(&user_info->group_sid, &domain->sid, 455 ctr->info.id21->group_rid); 456 user_info->acct_name = unistr2_tdup(mem_ctx, 457 &ctr->info.id21->uni_user_name); 458 user_info->full_name = unistr2_tdup(mem_ctx, 459 &ctr->info.id21->uni_full_name); 460 user_info->homedir = NULL; 461 user_info->shell = NULL; 462 user_info->primary_gid = (gid_t)-1; 463 464 return NT_STATUS_OK; 465} 466 467/* Lookup groups a user is a member of. I wish Unix had a call like this! */ 468static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 469 TALLOC_CTX *mem_ctx, 470 const DOM_SID *user_sid, 471 uint32 *num_groups, DOM_SID **user_grpsids) 472{ 473 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 474 POLICY_HND dom_pol, user_pol; 475 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; 476 DOM_GID *user_groups; 477 unsigned int i; 478 fstring sid_string; 479 uint32 user_rid; 480 struct rpc_pipe_client *cli; 481 482 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", 483 sid_to_string(sid_string, user_sid))); 484 485 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 486 return NT_STATUS_UNSUCCESSFUL; 487 488 *num_groups = 0; 489 *user_grpsids = NULL; 490 491 /* so lets see if we have a cached user_info_3 */ 492 result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 493 num_groups, user_grpsids); 494 495 if (NT_STATUS_IS_OK(result)) { 496 return NT_STATUS_OK; 497 } 498 499 /* no cache; hit the wire */ 500 501 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 502 if (!NT_STATUS_IS_OK(result)) 503 return result; 504 505 /* Get user handle */ 506 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol, 507 des_access, user_rid, &user_pol); 508 509 if (!NT_STATUS_IS_OK(result)) 510 return result; 511 512 /* Query user rids */ 513 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol, 514 num_groups, &user_groups); 515 516 rpccli_samr_close(cli, mem_ctx, &user_pol); 517 518 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) 519 return result; 520 521 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups); 522 if (!(*user_grpsids)) 523 return NT_STATUS_NO_MEMORY; 524 525 for (i=0;i<(*num_groups);i++) { 526 sid_copy(&((*user_grpsids)[i]), &domain->sid); 527 sid_append_rid(&((*user_grpsids)[i]), 528 user_groups[i].g_rid); 529 } 530 531 return NT_STATUS_OK; 532} 533 534NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, 535 TALLOC_CTX *mem_ctx, 536 uint32 num_sids, const DOM_SID *sids, 537 uint32 *num_aliases, uint32 **alias_rids) 538{ 539 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 540 POLICY_HND dom_pol; 541 DOM_SID2 *query_sids; 542 uint32 num_query_sids = 0; 543 int i; 544 struct rpc_pipe_client *cli; 545 uint32 *alias_rids_query, num_aliases_query; 546 int rangesize = MAX_SAM_ENTRIES_W2K; 547 uint32 total_sids = 0; 548 int num_queries = 1; 549 550 *num_aliases = 0; 551 *alias_rids = NULL; 552 553 DEBUG(3,("rpc: lookup_useraliases\n")); 554 555 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 556 if (!NT_STATUS_IS_OK(result)) 557 return result; 558 559 do { 560 /* prepare query */ 561 562 num_query_sids = MIN(num_sids - total_sids, rangesize); 563 564 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 565 num_queries, num_query_sids)); 566 567 if (num_query_sids) { 568 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids); 569 if (query_sids == NULL) { 570 return NT_STATUS_NO_MEMORY; 571 } 572 } else { 573 query_sids = NULL; 574 } 575 576 for (i=0; i<num_query_sids; i++) { 577 sid_copy(&query_sids[i].sid, &sids[total_sids++]); 578 query_sids[i].num_auths = query_sids[i].sid.num_auths; 579 } 580 581 /* do request */ 582 583 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol, 584 num_query_sids, query_sids, 585 &num_aliases_query, 586 &alias_rids_query); 587 588 if (!NT_STATUS_IS_OK(result)) { 589 *num_aliases = 0; 590 *alias_rids = NULL; 591 TALLOC_FREE(query_sids); 592 goto done; 593 } 594 595 /* process output */ 596 597 for (i=0; i<num_aliases_query; i++) { 598 size_t na = *num_aliases; 599 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i], 600 alias_rids, &na)) { 601 return NT_STATUS_NO_MEMORY; 602 } 603 *num_aliases = na; 604 } 605 606 TALLOC_FREE(query_sids); 607 608 num_queries++; 609 610 } while (total_sids < num_sids); 611 612 done: 613 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries " 614 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize)); 615 616 return result; 617} 618 619 620/* Lookup group membership given a rid. */ 621static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 622 TALLOC_CTX *mem_ctx, 623 const DOM_SID *group_sid, uint32 *num_names, 624 DOM_SID **sid_mem, char ***names, 625 uint32 **name_types) 626{ 627 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 628 uint32 i, total_names = 0; 629 POLICY_HND dom_pol, group_pol; 630 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; 631 uint32 *rid_mem = NULL; 632 uint32 group_rid; 633 unsigned int j; 634 fstring sid_string; 635 struct rpc_pipe_client *cli; 636 unsigned int orig_timeout; 637 638 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, 639 sid_to_string(sid_string, group_sid))); 640 641 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) 642 return NT_STATUS_UNSUCCESSFUL; 643 644 *num_names = 0; 645 646 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 647 if (!NT_STATUS_IS_OK(result)) 648 return result; 649 650 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol, 651 des_access, group_rid, &group_pol); 652 653 if (!NT_STATUS_IS_OK(result)) 654 return result; 655 656 /* Step #1: Get a list of user rids that are the members of the 657 group. */ 658 659 /* This call can take a long time - allow the server to time out. 660 35 seconds should do it. */ 661 662 orig_timeout = cli_set_timeout(cli->cli, 35000); 663 664 result = rpccli_samr_query_groupmem(cli, mem_ctx, 665 &group_pol, num_names, &rid_mem, 666 name_types); 667 668 /* And restore our original timeout. */ 669 cli_set_timeout(cli->cli, orig_timeout); 670 671 rpccli_samr_close(cli, mem_ctx, &group_pol); 672 673 if (!NT_STATUS_IS_OK(result)) 674 return result; 675 676 if (!*num_names) { 677 names = NULL; 678 name_types = NULL; 679 sid_mem = NULL; 680 return NT_STATUS_OK; 681 } 682 683 /* Step #2: Convert list of rids into list of usernames. Do this 684 in bunches of ~1000 to avoid crashing NT4. It looks like there 685 is a buffer overflow or something like that lurking around 686 somewhere. */ 687 688#define MAX_LOOKUP_RIDS 900 689 690 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names); 691 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names); 692 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names); 693 694 for (j=0;j<(*num_names);j++) 695 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]); 696 697 if (*num_names>0 && (!*names || !*name_types)) 698 return NT_STATUS_NO_MEMORY; 699 700 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) { 701 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS); 702 uint32 tmp_num_names = 0; 703 char **tmp_names = NULL; 704 uint32 *tmp_types = NULL; 705 706 /* Lookup a chunk of rids */ 707 708 result = rpccli_samr_lookup_rids(cli, mem_ctx, 709 &dom_pol, 710 num_lookup_rids, 711 &rid_mem[i], 712 &tmp_num_names, 713 &tmp_names, &tmp_types); 714 715 /* see if we have a real error (and yes the 716 STATUS_SOME_UNMAPPED is the one returned from 2k) */ 717 718 if (!NT_STATUS_IS_OK(result) && 719 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) 720 return result; 721 722 /* Copy result into array. The talloc system will take 723 care of freeing the temporary arrays later on. */ 724 725 memcpy(&(*names)[i], tmp_names, sizeof(char *) * 726 tmp_num_names); 727 728 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) * 729 tmp_num_names); 730 731 total_names += tmp_num_names; 732 } 733 734 *num_names = total_names; 735 736 return NT_STATUS_OK; 737} 738 739#ifdef HAVE_LDAP 740 741#include <ldap.h> 742 743static int get_ldap_seq(const char *server, int port, uint32 *seq) 744{ 745 int ret = -1; 746 struct timeval to; 747 const char *attrs[] = {"highestCommittedUSN", NULL}; 748 LDAPMessage *res = NULL; 749 char **values = NULL; 750 LDAP *ldp = NULL; 751 752 *seq = DOM_SEQUENCE_NONE; 753 754 /* 755 * Parameterised (5) second timeout on open. This is needed as the 756 * search timeout doesn't seem to apply to doing an open as well. JRA. 757 */ 758 759 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout()); 760 if (ldp == NULL) 761 return -1; 762 763 /* Timeout if no response within 20 seconds. */ 764 to.tv_sec = 10; 765 to.tv_usec = 0; 766 767 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", 768 CONST_DISCARD(char **, attrs), 0, &to, &res)) 769 goto done; 770 771 if (ldap_count_entries(ldp, res) != 1) 772 goto done; 773 774 values = ldap_get_values(ldp, res, "highestCommittedUSN"); 775 if (!values || !values[0]) 776 goto done; 777 778 *seq = atoi(values[0]); 779 ret = 0; 780 781 done: 782 783 if (values) 784 ldap_value_free(values); 785 if (res) 786 ldap_msgfree(res); 787 if (ldp) 788 ldap_unbind(ldp); 789 return ret; 790} 791 792/********************************************************************** 793 Get the sequence number for a Windows AD native mode domain using 794 LDAP queries. 795**********************************************************************/ 796 797static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq) 798{ 799 int ret = -1; 800 fstring ipstr; 801 802 fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr)); 803 if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) { 804 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence " 805 "number for Domain (%s) from DC (%s)\n", 806 domain->name, ipstr)); 807 } 808 return ret; 809} 810 811#endif /* HAVE_LDAP */ 812 813/* find the sequence number for a domain */ 814static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) 815{ 816 TALLOC_CTX *mem_ctx; 817 SAM_UNK_CTR ctr; 818 NTSTATUS result; 819 POLICY_HND dom_pol; 820 BOOL got_seq_num = False; 821 struct rpc_pipe_client *cli; 822 823 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); 824 825 *seq = DOM_SEQUENCE_NONE; 826 827 if (!(mem_ctx = talloc_init("sequence_number[rpc]"))) 828 return NT_STATUS_NO_MEMORY; 829 830#ifdef HAVE_LDAP 831 if ( domain->native_mode ) 832 { 833 int res; 834 835 DEBUG(8,("using get_ldap_seq() to retrieve the " 836 "sequence number\n")); 837 838 res = get_ldap_sequence_number( domain, seq ); 839 if (res == 0) 840 { 841 result = NT_STATUS_OK; 842 DEBUG(10,("domain_sequence_number: LDAP for " 843 "domain %s is %u\n", 844 domain->name, *seq)); 845 goto done; 846 } 847 848 DEBUG(10,("domain_sequence_number: failed to get LDAP " 849 "sequence number for domain %s\n", 850 domain->name )); 851 } 852#endif /* HAVE_LDAP */ 853 854 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 855 if (!NT_STATUS_IS_OK(result)) { 856 goto done; 857 } 858 859 /* Query domain info */ 860 861 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr); 862 863 if (NT_STATUS_IS_OK(result)) { 864 *seq = ctr.info.inf8.seq_num; 865 got_seq_num = True; 866 goto seq_num; 867 } 868 869 /* retry with info-level 2 in case the dc does not support info-level 8 870 * (like all older samba2 and samba3 dc's - Guenther */ 871 872 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr); 873 874 if (NT_STATUS_IS_OK(result)) { 875 *seq = ctr.info.inf2.seq_num; 876 got_seq_num = True; 877 } 878 879 seq_num: 880 if (got_seq_num) { 881 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", 882 domain->name, (unsigned)*seq)); 883 } else { 884 DEBUG(10,("domain_sequence_number: failed to get sequence " 885 "number (%u) for domain %s\n", 886 (unsigned)*seq, domain->name )); 887 } 888 889 done: 890 891 talloc_destroy(mem_ctx); 892 893 return result; 894} 895 896/* get a list of trusted domains */ 897static NTSTATUS trusted_domains(struct winbindd_domain *domain, 898 TALLOC_CTX *mem_ctx, 899 uint32 *num_domains, 900 char ***names, 901 char ***alt_names, 902 DOM_SID **dom_sids) 903{ 904 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 905 uint32 enum_ctx = 0; 906 struct rpc_pipe_client *cli; 907 POLICY_HND lsa_policy; 908 909 DEBUG(3,("rpc: trusted_domains\n")); 910 911 *num_domains = 0; 912 *names = NULL; 913 *alt_names = NULL; 914 *dom_sids = NULL; 915 916 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 917 if (!NT_STATUS_IS_OK(result)) 918 return result; 919 920 result = STATUS_MORE_ENTRIES; 921 922 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 923 uint32 start_idx, num; 924 char **tmp_names; 925 DOM_SID *tmp_sids; 926 int i; 927 928 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx, 929 &lsa_policy, &enum_ctx, 930 &num, &tmp_names, 931 &tmp_sids); 932 933 if (!NT_STATUS_IS_OK(result) && 934 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 935 break; 936 937 start_idx = *num_domains; 938 *num_domains += num; 939 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names, 940 char *, *num_domains); 941 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids, 942 DOM_SID, *num_domains); 943 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names, 944 char *, *num_domains); 945 if ((*names == NULL) || (*dom_sids == NULL) || 946 (*alt_names == NULL)) 947 return NT_STATUS_NO_MEMORY; 948 949 for (i=0; i<num; i++) { 950 (*names)[start_idx+i] = tmp_names[i]; 951 (*dom_sids)[start_idx+i] = tmp_sids[i]; 952 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, ""); 953 } 954 } 955 return result; 956} 957 958/* find the lockout policy for a domain */ 959NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, 960 TALLOC_CTX *mem_ctx, 961 SAM_UNK_INFO_12 *lockout_policy) 962{ 963 NTSTATUS result; 964 struct rpc_pipe_client *cli; 965 POLICY_HND dom_pol; 966 SAM_UNK_CTR ctr; 967 968 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name)); 969 970 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 971 if (!NT_STATUS_IS_OK(result)) { 972 goto done; 973 } 974 975 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr); 976 if (!NT_STATUS_IS_OK(result)) { 977 goto done; 978 } 979 980 *lockout_policy = ctr.info.inf12; 981 982 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n", 983 ctr.info.inf12.bad_attempt_lockout)); 984 985 done: 986 987 return result; 988} 989 990/* find the password policy for a domain */ 991NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, 992 TALLOC_CTX *mem_ctx, 993 SAM_UNK_INFO_1 *password_policy) 994{ 995 NTSTATUS result; 996 struct rpc_pipe_client *cli; 997 POLICY_HND dom_pol; 998 SAM_UNK_CTR ctr; 999 1000 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name)); 1001 1002 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 1003 if (!NT_STATUS_IS_OK(result)) { 1004 goto done; 1005 } 1006 1007 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr); 1008 if (!NT_STATUS_IS_OK(result)) { 1009 goto done; 1010 } 1011 1012 *password_policy = ctr.info.inf1; 1013 1014 DEBUG(10,("msrpc_password_policy: min_length_password %d\n", 1015 ctr.info.inf1.min_length_password)); 1016 1017 done: 1018 1019 return result; 1020} 1021 1022 1023/* the rpc backend methods are exposed via this structure */ 1024struct winbindd_methods msrpc_methods = { 1025 False, 1026 query_user_list, 1027 enum_dom_groups, 1028 enum_local_groups, 1029 msrpc_name_to_sid, 1030 msrpc_sid_to_name, 1031 msrpc_rids_to_names, 1032 query_user, 1033 lookup_usergroups, 1034 msrpc_lookup_useraliases, 1035 lookup_groupmem, 1036 sequence_number, 1037 msrpc_lockout_policy, 1038 msrpc_password_policy, 1039 trusted_domains, 1040}; 1041