1/* 2 Unix SMB/CIFS implementation. 3 4 Winbind daemon for ntdom nss module 5 6 Copyright (C) Tim Potter 2000-2001 7 Copyright (C) 2001 by Martin Pool <mbp@samba.org> 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25#include "winbindd.h" 26 27#undef DBGC_CLASS 28#define DBGC_CLASS DBGC_WINBIND 29 30/** 31 * @file winbindd_util.c 32 * 33 * Winbind daemon for NT domain authentication nss module. 34 **/ 35 36 37/** 38 * Used to clobber name fields that have an undefined value. 39 * 40 * Correct code should never look at a field that has this value. 41 **/ 42 43static const fstring name_deadbeef = "<deadbeef>"; 44 45/* The list of trusted domains. Note that the list can be deleted and 46 recreated using the init_domain_list() function so pointers to 47 individual winbindd_domain structures cannot be made. Keep a copy of 48 the domain name instead. */ 49 50static struct winbindd_domain *_domain_list; 51 52/** 53 When was the last scan of trusted domains done? 54 55 0 == not ever 56*/ 57 58static time_t last_trustdom_scan; 59 60struct winbindd_domain *domain_list(void) 61{ 62 /* Initialise list */ 63 64 if (!_domain_list) 65 if (!init_domain_list()) 66 return NULL; 67 68 return _domain_list; 69} 70 71/* Free all entries in the trusted domain list */ 72 73void free_domain_list(void) 74{ 75 struct winbindd_domain *domain = _domain_list; 76 77 while(domain) { 78 struct winbindd_domain *next = domain->next; 79 80 DLIST_REMOVE(_domain_list, domain); 81 SAFE_FREE(domain); 82 domain = next; 83 } 84} 85 86 87/* Add a trusted domain to our list of domains */ 88static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, 89 struct winbindd_methods *methods, 90 DOM_SID *sid) 91{ 92 struct winbindd_domain *domain; 93 const char *alternative_name = NULL; 94 static const DOM_SID null_sid; 95 96 /* ignore alt_name if we are not in an AD domain */ 97 98 if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) { 99 alternative_name = alt_name; 100 } 101 102 /* We can't call domain_list() as this function is called from 103 init_domain_list() and we'll get stuck in a loop. */ 104 for (domain = _domain_list; domain; domain = domain->next) { 105 if (strequal(domain_name, domain->name) || 106 strequal(domain_name, domain->alt_name)) { 107 return domain; 108 } 109 if (alternative_name && *alternative_name) { 110 if (strequal(alternative_name, domain->name) || 111 strequal(alternative_name, domain->alt_name)) { 112 return domain; 113 } 114 } 115 if (sid) { 116 if (sid_equal(sid, &null_sid) ) { 117 118 } else if (sid_equal(sid, &domain->sid)) { 119 return domain; 120 } 121 } 122 } 123 124 /* Create new domain entry */ 125 126 if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) 127 return NULL; 128 129 /* Fill in fields */ 130 131 ZERO_STRUCTP(domain); 132 133 /* prioritise the short name */ 134 if (strchr_m(domain_name, '.') && alternative_name && *alternative_name) { 135 fstrcpy(domain->name, alternative_name); 136 fstrcpy(domain->alt_name, domain_name); 137 } else { 138 fstrcpy(domain->name, domain_name); 139 if (alternative_name) { 140 fstrcpy(domain->alt_name, alternative_name); 141 } 142 } 143 144 domain->methods = methods; 145 domain->backend = NULL; 146 domain->sequence_number = DOM_SEQUENCE_NONE; 147 domain->last_seq_check = 0; 148 if (sid) { 149 sid_copy(&domain->sid, sid); 150 } 151 152 /* set flags about native_mode, active_directory */ 153 154 set_dc_type_and_flags( domain ); 155 156 DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, 157 domain->active_directory ? "ADS" : "NT4", 158 domain->native_mode ? "native mode" : 159 ((domain->active_directory && !domain->native_mode) ? "mixed mode" : ""))); 160 161 /* Link to domain list */ 162 DLIST_ADD(_domain_list, domain); 163 164 DEBUG(1,("Added domain %s %s %s\n", 165 domain->name, domain->alt_name, 166 &domain->sid?sid_string_static(&domain->sid):"")); 167 168 return domain; 169} 170 171/******************************************************************** 172 Periodically we need to refresh the trusted domain cache for smbd 173********************************************************************/ 174 175void rescan_trusted_domains( void ) 176{ 177 time_t now = time(NULL); 178 struct winbindd_domain *mydomain = NULL; 179 180 /* see if the time has come... */ 181 182 if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) 183 return; 184 185 if ( (mydomain = find_our_domain()) == NULL ) { 186 DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n")); 187 return; 188 } 189 190 /* this will only add new domains we didn't already know about */ 191 192 add_trusted_domains( mydomain ); 193 194 last_trustdom_scan = now; 195 196 return; 197} 198 199/******************************************************************** 200 rescan our domains looking for new trusted domains 201********************************************************************/ 202 203void add_trusted_domains( struct winbindd_domain *domain ) 204{ 205 TALLOC_CTX *mem_ctx; 206 NTSTATUS result; 207 time_t t; 208 char **names; 209 char **alt_names; 210 int num_domains = 0; 211 DOM_SID *dom_sids, null_sid; 212 int i; 213 struct winbindd_domain *new_domain; 214 215 /* trusted domains might be disabled */ 216 if (!lp_allow_trusted_domains()) { 217 return; 218 } 219 220 DEBUG(5, ("scanning trusted domain list\n")); 221 222 if (!(mem_ctx = talloc_init("init_domain_list"))) 223 return; 224 225 ZERO_STRUCTP(&null_sid); 226 227 t = time(NULL); 228 229 /* ask the DC what domains it trusts */ 230 231 result = domain->methods->trusted_domains(domain, mem_ctx, (unsigned int *)&num_domains, 232 &names, &alt_names, &dom_sids); 233 234 if ( NT_STATUS_IS_OK(result) ) { 235 236 /* Add each domain to the trusted domain list */ 237 238 for(i = 0; i < num_domains; i++) { 239 DEBUG(10,("Found domain %s\n", names[i])); 240 add_trusted_domain(names[i], alt_names?alt_names[i]:NULL, 241 domain->methods, &dom_sids[i]); 242 243 /* if the SID was empty, we better set it now */ 244 245 if ( sid_equal(&dom_sids[i], &null_sid) ) { 246 247 new_domain = find_domain_from_name(names[i]); 248 249 /* this should never happen */ 250 if ( !new_domain ) { 251 DEBUG(0,("rescan_trust_domains: can't find the domain I just added! [%s]\n", 252 names[i])); 253 break; 254 } 255 256 /* call the cache method; which will operate on the winbindd_domain \ 257 passed in and choose either rpc or ads as appropriate */ 258 259 result = domain->methods->domain_sid( new_domain, &new_domain->sid ); 260 261 if ( NT_STATUS_IS_OK(result) ) 262 sid_copy( &dom_sids[i], &new_domain->sid ); 263 } 264 265 /* store trusted domain in the cache */ 266 trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL, 267 &dom_sids[i], t + WINBINDD_RESCAN_FREQ); 268 } 269 } 270 271 talloc_destroy(mem_ctx); 272} 273 274/* Look up global info for the winbind daemon */ 275BOOL init_domain_list(void) 276{ 277 extern struct winbindd_methods cache_methods; 278 struct winbindd_domain *domain; 279 280 /* Free existing list */ 281 free_domain_list(); 282 283 /* Add ourselves as the first entry. */ 284 285 domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL); 286 287 domain->primary = True; 288 289 /* get any alternate name for the primary domain */ 290 291 cache_methods.alternate_name(domain); 292 293 /* now we have the correct netbios (short) domain name */ 294 295 if ( *domain->name ) 296 set_global_myworkgroup( domain->name ); 297 298 if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) { 299 DEBUG(1, ("Could not fetch sid for our domain %s\n", 300 domain->name)); 301 return False; 302 } 303 304 /* do an initial scan for trusted domains */ 305 add_trusted_domains(domain); 306 307 /* avoid rescanning this right away */ 308 last_trustdom_scan = time(NULL); 309 return True; 310} 311 312/** 313 * Given a domain name, return the struct winbindd domain info for it 314 * 315 * @note Do *not* pass lp_workgroup() to this function. domain_list 316 * may modify it's value, and free that pointer. Instead, our local 317 * domain may be found by calling find_our_domain(). 318 * directly. 319 * 320 * 321 * @return The domain structure for the named domain, if it is working. 322 */ 323 324struct winbindd_domain *find_domain_from_name(const char *domain_name) 325{ 326 struct winbindd_domain *domain; 327 328 /* Search through list */ 329 330 for (domain = domain_list(); domain != NULL; domain = domain->next) { 331 if (strequal(domain_name, domain->name) || 332 (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) { 333 return domain; 334 } 335 } 336 337 /* Not found */ 338 339 return NULL; 340} 341 342/* Given a domain sid, return the struct winbindd domain info for it */ 343 344struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) 345{ 346 struct winbindd_domain *domain; 347 348 /* Search through list */ 349 350 for (domain = domain_list(); domain != NULL; domain = domain->next) { 351 if (sid_compare_domain(sid, &domain->sid) == 0) 352 return domain; 353 } 354 355 /* Not found */ 356 357 return NULL; 358} 359 360/* Given a domain sid, return the struct winbindd domain info for it */ 361 362struct winbindd_domain *find_our_domain(void) 363{ 364 struct winbindd_domain *domain; 365 366 /* Search through list */ 367 368 for (domain = domain_list(); domain != NULL; domain = domain->next) { 369 if (domain->primary) 370 return domain; 371 } 372 373 /* Not found */ 374 375 return NULL; 376} 377 378/* Lookup a sid in a domain from a name */ 379 380BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, 381 const char *name, DOM_SID *sid, 382 enum SID_NAME_USE *type) 383{ 384 NTSTATUS result; 385 TALLOC_CTX *mem_ctx; 386 387 mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name); 388 if (!mem_ctx) 389 return False; 390 391 /* Lookup name */ 392 result = domain->methods->name_to_sid(domain, mem_ctx, name, sid, type); 393 394 talloc_destroy(mem_ctx); 395 396 /* Return rid and type if lookup successful */ 397 if (!NT_STATUS_IS_OK(result)) { 398 *type = SID_NAME_UNKNOWN; 399 } 400 401 return NT_STATUS_IS_OK(result); 402} 403 404/** 405 * @brief Lookup a name in a domain from a sid. 406 * 407 * @param sid Security ID you want to look up. 408 * @param name On success, set to the name corresponding to @p sid. 409 * @param dom_name On success, set to the 'domain name' corresponding to @p sid. 410 * @param type On success, contains the type of name: alias, group or 411 * user. 412 * @retval True if the name exists, in which case @p name and @p type 413 * are set, otherwise False. 414 **/ 415BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, 416 fstring dom_name, 417 fstring name, 418 enum SID_NAME_USE *type) 419{ 420 char *names; 421 NTSTATUS result; 422 TALLOC_CTX *mem_ctx; 423 BOOL rv = False; 424 struct winbindd_domain *domain; 425 426 domain = find_domain_from_sid(sid); 427 428 if (!domain) { 429 DEBUG(1,("Can't find domain from sid\n")); 430 return False; 431 } 432 433 /* Lookup name */ 434 435 if (!(mem_ctx = talloc_init("winbindd_lookup_name_by_sid"))) 436 return False; 437 438 result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type); 439 440 /* Return name and type if successful */ 441 442 if ((rv = NT_STATUS_IS_OK(result))) { 443 fstrcpy(dom_name, domain->name); 444 fstrcpy(name, names); 445 } else { 446 *type = SID_NAME_UNKNOWN; 447 fstrcpy(name, name_deadbeef); 448 } 449 450 talloc_destroy(mem_ctx); 451 452 return rv; 453} 454 455 456/* Free state information held for {set,get,end}{pw,gr}ent() functions */ 457 458void free_getent_state(struct getent_state *state) 459{ 460 struct getent_state *temp; 461 462 /* Iterate over state list */ 463 464 temp = state; 465 466 while(temp != NULL) { 467 struct getent_state *next; 468 469 /* Free sam entries then list entry */ 470 471 SAFE_FREE(state->sam_entries); 472 DLIST_REMOVE(state, state); 473 next = temp->next; 474 475 SAFE_FREE(temp); 476 temp = next; 477 } 478} 479 480/* Parse winbindd related parameters */ 481 482BOOL winbindd_param_init(void) 483{ 484 /* Parse winbind uid and winbind_gid parameters */ 485 486 if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) { 487 DEBUG(0, ("winbindd: idmap uid range missing or invalid\n")); 488 DEBUG(0, ("winbindd: cannot continue, exiting.\n")); 489 return False; 490 } 491 492 if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) { 493 DEBUG(0, ("winbindd: idmap gid range missing or invalid\n")); 494 DEBUG(0, ("winbindd: cannot continue, exiting.\n")); 495 return False; 496 } 497 498 return True; 499} 500 501/* Check if a domain is present in a comma-separated list of domains */ 502 503BOOL check_domain_env(char *domain_env, char *domain) 504{ 505 fstring name; 506 const char *tmp = domain_env; 507 508 while(next_token(&tmp, name, ",", sizeof(fstring))) { 509 if (strequal(name, domain)) 510 return True; 511 } 512 513 return False; 514} 515 516/* Is this a domain which we may assume no DOMAIN\ prefix? */ 517 518static BOOL assume_domain(const char *domain) { 519 if ((lp_winbind_use_default_domain() 520 || lp_winbind_trusted_domains_only()) && 521 strequal(lp_workgroup(), domain)) 522 return True; 523 524 if (strequal(get_global_sam_name(), domain)) 525 return True; 526 527 return False; 528} 529 530/* Parse a string of the form DOMAIN/user into a domain and a user */ 531 532BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) 533{ 534 char *p = strchr(domuser,*lp_winbind_separator()); 535 536 if ( !p ) { 537 fstrcpy(user, domuser); 538 539 if ( assume_domain(lp_workgroup())) { 540 fstrcpy(domain, lp_workgroup()); 541 } else { 542 fstrcpy( domain, get_global_sam_name() ); 543 } 544 } 545 else { 546 fstrcpy(user, p+1); 547 fstrcpy(domain, domuser); 548 domain[PTR_DIFF(p, domuser)] = 0; 549 } 550 551 strupper_m(domain); 552 553 return True; 554} 555 556/* 557 Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and 558 'winbind separator' options. 559 This means: 560 - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is 561 lp_workgroup() 562 563 If we are a PDC or BDC, and this is for our domain, do likewise. 564 565 Also, if omit DOMAIN if 'winbind trusted domains only = true', as the 566 username is then unqualified in unix 567 568*/ 569void fill_domain_username(fstring name, const char *domain, const char *user) 570{ 571 if (assume_domain(domain)) { 572 strlcpy(name, user, sizeof(fstring)); 573 } else { 574 slprintf(name, sizeof(fstring) - 1, "%s%s%s", 575 domain, lp_winbind_separator(), 576 user); 577 } 578} 579 580/* 581 * Winbindd socket accessor functions 582 */ 583 584char *get_winbind_priv_pipe_dir(void) 585{ 586 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); 587} 588 589/* Open the winbindd socket */ 590 591static int _winbindd_socket = -1; 592static int _winbindd_priv_socket = -1; 593 594int open_winbindd_socket(void) 595{ 596 if (_winbindd_socket == -1) { 597 _winbindd_socket = create_pipe_sock( 598 WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755); 599 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n", 600 _winbindd_socket)); 601 } 602 603 return _winbindd_socket; 604} 605 606int open_winbindd_priv_socket(void) 607{ 608 if (_winbindd_priv_socket == -1) { 609 _winbindd_priv_socket = create_pipe_sock( 610 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750); 611 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n", 612 _winbindd_priv_socket)); 613 } 614 615 return _winbindd_priv_socket; 616} 617 618/* Close the winbindd socket */ 619 620void close_winbindd_socket(void) 621{ 622 if (_winbindd_socket != -1) { 623 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", 624 _winbindd_socket)); 625 close(_winbindd_socket); 626 _winbindd_socket = -1; 627 } 628 if (_winbindd_priv_socket != -1) { 629 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", 630 _winbindd_priv_socket)); 631 close(_winbindd_priv_socket); 632 _winbindd_priv_socket = -1; 633 } 634} 635 636/* 637 * Client list accessor functions 638 */ 639 640static struct winbindd_cli_state *_client_list; 641static int _num_clients; 642 643/* Return list of all connected clients */ 644 645struct winbindd_cli_state *winbindd_client_list(void) 646{ 647 return _client_list; 648} 649 650/* Add a connection to the list */ 651 652void winbindd_add_client(struct winbindd_cli_state *cli) 653{ 654 DLIST_ADD(_client_list, cli); 655 _num_clients++; 656} 657 658/* Remove a client from the list */ 659 660void winbindd_remove_client(struct winbindd_cli_state *cli) 661{ 662 DLIST_REMOVE(_client_list, cli); 663 _num_clients--; 664} 665 666/* Close all open clients */ 667 668void winbindd_kill_all_clients(void) 669{ 670 struct winbindd_cli_state *cl = winbindd_client_list(); 671 672 DEBUG(10, ("winbindd_kill_all_clients: going postal\n")); 673 674 while (cl) { 675 struct winbindd_cli_state *next; 676 677 next = cl->next; 678 winbindd_remove_client(cl); 679 cl = next; 680 } 681} 682 683/* Return number of open clients */ 684 685int winbindd_num_clients(void) 686{ 687 return _num_clients; 688} 689 690/* Help with RID -> SID conversion */ 691 692DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain, 693 TALLOC_CTX *mem_ctx, 694 uint32 rid) 695{ 696 DOM_SID *sid; 697 sid = talloc(mem_ctx, sizeof(*sid)); 698 if (!sid) { 699 smb_panic("rid_to_to_talloced_sid: talloc for DOM_SID failed!\n"); 700 } 701 sid_copy(sid, &domain->sid); 702 sid_append_rid(sid, rid); 703 return sid; 704} 705 706/***************************************************************************** 707 For idmap conversion: convert one record to new format 708 Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid 709 instead of the SID. 710*****************************************************************************/ 711static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state) 712{ 713 struct winbindd_domain *domain; 714 char *p; 715 DOM_SID sid; 716 uint32 rid; 717 fstring keystr; 718 fstring dom_name; 719 TDB_DATA key2; 720 BOOL *failed = (BOOL *)state; 721 722 DEBUG(10,("Converting %s\n", key.dptr)); 723 724 p = strchr(key.dptr, '/'); 725 if (!p) 726 return 0; 727 728 *p = 0; 729 fstrcpy(dom_name, key.dptr); 730 *p++ = '/'; 731 732 domain = find_domain_from_name(dom_name); 733 if (domain == NULL) { 734 /* We must delete the old record. */ 735 DEBUG(0,("Unable to find domain %s\n", dom_name )); 736 DEBUG(0,("deleting record %s\n", key.dptr )); 737 738 if (tdb_delete(tdb, key) != 0) { 739 DEBUG(0, ("Unable to delete record %s\n", key.dptr)); 740 *failed = True; 741 return -1; 742 } 743 744 return 0; 745 } 746 747 rid = atoi(p); 748 749 sid_copy(&sid, &domain->sid); 750 sid_append_rid(&sid, rid); 751 752 sid_to_string(keystr, &sid); 753 key2.dptr = keystr; 754 key2.dsize = strlen(keystr) + 1; 755 756 if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) { 757 DEBUG(0,("Unable to add record %s\n", key2.dptr )); 758 *failed = True; 759 return -1; 760 } 761 762 if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) { 763 DEBUG(0,("Unable to update record %s\n", data.dptr )); 764 *failed = True; 765 return -1; 766 } 767 768 if (tdb_delete(tdb, key) != 0) { 769 DEBUG(0,("Unable to delete record %s\n", key.dptr )); 770 *failed = True; 771 return -1; 772 } 773 774 return 0; 775} 776 777/* These definitions are from sam/idmap_tdb.c. Replicated here just 778 out of laziness.... :-( */ 779 780/* High water mark keys */ 781#define HWM_GROUP "GROUP HWM" 782#define HWM_USER "USER HWM" 783 784/* idmap version determines auto-conversion */ 785#define IDMAP_VERSION 2 786 787 788/***************************************************************************** 789 Convert the idmap database from an older version. 790*****************************************************************************/ 791 792static BOOL idmap_convert(const char *idmap_name) 793{ 794 int32 vers; 795 BOOL bigendianheader; 796 BOOL failed = False; 797 TDB_CONTEXT *idmap_tdb; 798 799 if (!(idmap_tdb = tdb_open_log(idmap_name, 0, 800 TDB_DEFAULT, O_RDWR, 801 0600))) { 802 DEBUG(0, ("idmap_convert: Unable to open idmap database\n")); 803 return False; 804 } 805 806 bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False; 807 808 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION"); 809 810 if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) { 811 /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */ 812 /* 813 * high and low records were created on a 814 * big endian machine and will need byte-reversing. 815 */ 816 817 int32 wm; 818 819 wm = tdb_fetch_int32(idmap_tdb, HWM_USER); 820 821 if (wm != -1) { 822 wm = IREV(wm); 823 } else { 824 wm = server_state.uid_low; 825 } 826 827 if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) { 828 DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n")); 829 tdb_close(idmap_tdb); 830 return False; 831 } 832 833 wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP); 834 if (wm != -1) { 835 wm = IREV(wm); 836 } else { 837 wm = server_state.gid_low; 838 } 839 840 if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) { 841 DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n")); 842 tdb_close(idmap_tdb); 843 return False; 844 } 845 } 846 847 /* the old format stored as DOMAIN/rid - now we store the SID direct */ 848 tdb_traverse(idmap_tdb, convert_fn, &failed); 849 850 if (failed) { 851 DEBUG(0, ("Problem during conversion\n")); 852 tdb_close(idmap_tdb); 853 return False; 854 } 855 856 if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) { 857 DEBUG(0, ("idmap_convert: Unable to dtore idmap version in databse\n")); 858 tdb_close(idmap_tdb); 859 return False; 860 } 861 862 tdb_close(idmap_tdb); 863 return True; 864} 865 866/***************************************************************************** 867 Convert the idmap database from an older version if necessary 868*****************************************************************************/ 869 870BOOL winbindd_upgrade_idmap(void) 871{ 872 pstring idmap_name; 873 pstring backup_name; 874 SMB_STRUCT_STAT stbuf; 875 TDB_CONTEXT *idmap_tdb; 876 877 pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb")); 878 879 if (!file_exist(idmap_name, &stbuf)) { 880 /* nothing to convert return */ 881 return True; 882 } 883 884 if (!(idmap_tdb = tdb_open_log(idmap_name, 0, 885 TDB_DEFAULT, O_RDWR, 886 0600))) { 887 DEBUG(0, ("idmap_convert: Unable to open idmap database\n")); 888 return False; 889 } 890 891 if (tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION") == IDMAP_VERSION) { 892 /* nothing to convert return */ 893 tdb_close(idmap_tdb); 894 return True; 895 } 896 897 /* backup_tdb expects the tdb not to be open */ 898 tdb_close(idmap_tdb); 899 900 DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n")); 901 902 pstrcpy(backup_name, idmap_name); 903 pstrcat(backup_name, ".bak"); 904 905 if (backup_tdb(idmap_name, backup_name) != 0) { 906 DEBUG(0, ("Could not backup idmap database\n")); 907 return False; 908 } 909 910 return idmap_convert(idmap_name); 911} 912 913/******************************************************************* 914 wrapper around retrieving the trust account password 915*******************************************************************/ 916 917BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], 918 time_t *pass_last_set_time, uint32 *channel) 919{ 920 DOM_SID sid; 921 char *pwd; 922 923 /* if we are a DC and this is not our domain, then lookup an account 924 for the domain trust */ 925 926 if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) 927 { 928 if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid, 929 pass_last_set_time) ) 930 { 931 DEBUG(0, ("get_trust_pw: could not fetch trust account " 932 "password for trusted domain %s\n", domain)); 933 return False; 934 } 935 936 *channel = SEC_CHAN_DOMAIN; 937 E_md4hash(pwd, ret_pwd); 938 SAFE_FREE(pwd); 939 940 return True; 941 } 942 else /* just get the account for our domain (covers 943 ROLE_DOMAIN_MEMBER as well */ 944 { 945 /* get the machine trust account for our domain */ 946 947 if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd, 948 pass_last_set_time, channel) ) 949 { 950 DEBUG(0, ("get_trust_pw: could not fetch trust account " 951 "password for my domain %s\n", domain)); 952 return False; 953 } 954 955 return True; 956 } 957 958 /* Failure */ 959} 960 961