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