1/* 2 Unix SMB/CIFS implementation. 3 SAM_ACCOUNT access routines 4 Copyright (C) Jeremy Allison 1996-2001 5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 6 Copyright (C) Gerald (Jerry) Carter 2000-2001 7 Copyright (C) Andrew Bartlett 2001-2002 8 Copyright (C) Stefan (metze) Metzmacher 2002 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 27#undef DBGC_CLASS 28#define DBGC_CLASS DBGC_PASSDB 29 30/** 31 * @todo Redefine this to NULL, but this changes the API because 32 * much of samba assumes that the pdb_get...() funtions 33 * return pstrings. (ie not null-pointers). 34 * See also pdb_fill_default_sam(). 35 */ 36 37#define PDB_NOT_QUITE_NULL "" 38 39/********************************************************************* 40 Collection of get...() functions for SAM_ACCOUNT. 41 ********************************************************************/ 42 43uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass) 44{ 45 if (sampass) 46 return (sampass->private.acct_ctrl); 47 else 48 return (ACB_DISABLED); 49} 50 51time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass) 52{ 53 if (sampass) 54 return (sampass->private.logon_time); 55 else 56 return (0); 57} 58 59time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass) 60{ 61 if (sampass) 62 return (sampass->private.logoff_time); 63 else 64 return (-1); 65} 66 67time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass) 68{ 69 if (sampass) 70 return (sampass->private.kickoff_time); 71 else 72 return (-1); 73} 74 75time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass) 76{ 77 if (sampass) 78 return (sampass->private.bad_password_time); 79 else 80 return (-1); 81} 82 83time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass) 84{ 85 if (sampass) 86 return (sampass->private.pass_last_set_time); 87 else 88 return (-1); 89} 90 91time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass) 92{ 93 if (sampass) 94 return (sampass->private.pass_can_change_time); 95 else 96 return (-1); 97} 98 99time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass) 100{ 101 if (sampass) 102 return (sampass->private.pass_must_change_time); 103 else 104 return (-1); 105} 106 107uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass) 108{ 109 if (sampass) 110 return (sampass->private.logon_divs); 111 else 112 return (-1); 113} 114 115uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass) 116{ 117 if (sampass) 118 return (sampass->private.hours_len); 119 else 120 return (-1); 121} 122 123const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass) 124{ 125 if (sampass) 126 return (sampass->private.hours); 127 else 128 return (NULL); 129} 130 131const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass) 132{ 133 if (sampass) { 134 SMB_ASSERT((!sampass->private.nt_pw.data) 135 || sampass->private.nt_pw.length == NT_HASH_LEN); 136 return ((uint8*)sampass->private.nt_pw.data); 137 } 138 else 139 return (NULL); 140} 141 142const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) 143{ 144 if (sampass) { 145 SMB_ASSERT((!sampass->private.lm_pw.data) 146 || sampass->private.lm_pw.length == LM_HASH_LEN); 147 return ((uint8*)sampass->private.lm_pw.data); 148 } 149 else 150 return (NULL); 151} 152 153const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_hist_len) 154{ 155 if (sampass) { 156 SMB_ASSERT((!sampass->private.nt_pw_his.data) 157 || ((sampass->private.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0)); 158 *current_hist_len = sampass->private.nt_pw_his.length / PW_HISTORY_ENTRY_LEN; 159 return ((uint8*)sampass->private.nt_pw_his.data); 160 } else { 161 *current_hist_len = 0; 162 return (NULL); 163 } 164} 165 166/* Return the plaintext password if known. Most of the time 167 it isn't, so don't assume anything magic about this function. 168 169 Used to pass the plaintext to passdb backends that might 170 want to store more than just the NTLM hashes. 171*/ 172const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) 173{ 174 if (sampass) { 175 return (sampass->private.plaintext_pw); 176 } 177 else 178 return (NULL); 179} 180const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass) 181{ 182 if (sampass) 183 return &sampass->private.user_sid; 184 else 185 return (NULL); 186} 187 188const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass) 189{ 190 if (sampass) 191 return &sampass->private.group_sid; 192 else 193 return (NULL); 194} 195 196/** 197 * Get flags showing what is initalised in the SAM_ACCOUNT 198 * @param sampass the SAM_ACCOUNT in question 199 * @return the flags indicating the members initialised in the struct. 200 **/ 201 202enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element) 203{ 204 enum pdb_value_state ret = PDB_DEFAULT; 205 206 if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags) 207 return ret; 208 209 if (bitmap_query(sampass->private.set_flags, element)) { 210 DEBUG(11, ("element %d: SET\n", element)); 211 ret = PDB_SET; 212 } 213 214 if (bitmap_query(sampass->private.change_flags, element)) { 215 DEBUG(11, ("element %d: CHANGED\n", element)); 216 ret = PDB_CHANGED; 217 } 218 219 if (ret == PDB_DEFAULT) { 220 DEBUG(11, ("element %d: DEFAULT\n", element)); 221 } 222 223 return ret; 224} 225 226const char* pdb_get_username (const SAM_ACCOUNT *sampass) 227{ 228 if (sampass) 229 return (sampass->private.username); 230 else 231 return (NULL); 232} 233 234const char* pdb_get_domain (const SAM_ACCOUNT *sampass) 235{ 236 if (sampass) 237 return (sampass->private.domain); 238 else 239 return (NULL); 240} 241 242const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass) 243{ 244 if (sampass) 245 return (sampass->private.nt_username); 246 else 247 return (NULL); 248} 249 250const char* pdb_get_fullname (const SAM_ACCOUNT *sampass) 251{ 252 if (sampass) 253 return (sampass->private.full_name); 254 else 255 return (NULL); 256} 257 258const char* pdb_get_homedir (const SAM_ACCOUNT *sampass) 259{ 260 if (sampass) 261 return (sampass->private.home_dir); 262 else 263 return (NULL); 264} 265 266const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass) 267{ 268 if (sampass) 269 return (sampass->private.unix_home_dir); 270 else 271 return (NULL); 272} 273 274const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass) 275{ 276 if (sampass) 277 return (sampass->private.dir_drive); 278 else 279 return (NULL); 280} 281 282const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass) 283{ 284 if (sampass) 285 return (sampass->private.logon_script); 286 else 287 return (NULL); 288} 289 290const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass) 291{ 292 if (sampass) 293 return (sampass->private.profile_path); 294 else 295 return (NULL); 296} 297 298const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass) 299{ 300 if (sampass) 301 return (sampass->private.acct_desc); 302 else 303 return (NULL); 304} 305 306const char* pdb_get_workstations (const SAM_ACCOUNT *sampass) 307{ 308 if (sampass) 309 return (sampass->private.workstations); 310 else 311 return (NULL); 312} 313 314const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass) 315{ 316 if (sampass) 317 return (sampass->private.unknown_str); 318 else 319 return (NULL); 320} 321 322const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) 323{ 324 if (sampass) 325 return (sampass->private.munged_dial); 326 else 327 return (NULL); 328} 329 330uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass) 331{ 332 if (sampass) 333 return (sampass->private.bad_password_count); 334 else 335 return 0; 336} 337 338uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass) 339{ 340 if (sampass) 341 return (sampass->private.logon_count); 342 else 343 return 0; 344} 345 346uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass) 347{ 348 if (sampass) 349 return (sampass->private.unknown_6); 350 else 351 return (-1); 352} 353 354void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods) 355{ 356 if (sampass && my_methods == sampass->private.backend_private_methods) 357 return sampass->private.backend_private_data; 358 else 359 return NULL; 360} 361 362/********************************************************************* 363 Collection of set...() functions for SAM_ACCOUNT. 364 ********************************************************************/ 365 366BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag) 367{ 368 if (!sampass) 369 return False; 370 371 sampass->private.acct_ctrl = acct_ctrl; 372 373 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag); 374} 375 376BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 377{ 378 if (!sampass) 379 return False; 380 381 sampass->private.logon_time = mytime; 382 383 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag); 384} 385 386BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 387{ 388 if (!sampass) 389 return False; 390 391 sampass->private.logoff_time = mytime; 392 393 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag); 394} 395 396BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 397{ 398 if (!sampass) 399 return False; 400 401 sampass->private.kickoff_time = mytime; 402 403 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag); 404} 405 406BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime, 407 enum pdb_value_state flag) 408{ 409 if (!sampass) 410 return False; 411 412 sampass->private.bad_password_time = mytime; 413 414 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag); 415} 416 417BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 418{ 419 if (!sampass) 420 return False; 421 422 sampass->private.pass_can_change_time = mytime; 423 424 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag); 425} 426 427BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 428{ 429 if (!sampass) 430 return False; 431 432 sampass->private.pass_must_change_time = mytime; 433 434 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag); 435} 436 437BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) 438{ 439 if (!sampass) 440 return False; 441 442 sampass->private.pass_last_set_time = mytime; 443 444 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag); 445} 446 447BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag) 448{ 449 if (!sampass) 450 return False; 451 452 sampass->private.hours_len = len; 453 454 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag); 455} 456 457BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag) 458{ 459 if (!sampass) 460 return False; 461 462 sampass->private.logon_divs = hours; 463 464 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag); 465} 466 467/** 468 * Set flags showing what is initalised in the SAM_ACCOUNT 469 * @param sampass the SAM_ACCOUNT in question 470 * @param flag The *new* flag to be set. Old flags preserved 471 * this flag is only added. 472 **/ 473 474BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag) 475{ 476 if (!sampass || !sampass->mem_ctx) 477 return False; 478 479 if (!sampass->private.set_flags) { 480 if ((sampass->private.set_flags = 481 bitmap_talloc(sampass->mem_ctx, 482 PDB_COUNT))==NULL) { 483 DEBUG(0,("bitmap_talloc failed\n")); 484 return False; 485 } 486 } 487 if (!sampass->private.change_flags) { 488 if ((sampass->private.change_flags = 489 bitmap_talloc(sampass->mem_ctx, 490 PDB_COUNT))==NULL) { 491 DEBUG(0,("bitmap_talloc failed\n")); 492 return False; 493 } 494 } 495 496 switch(value_flag) { 497 case PDB_CHANGED: 498 if (!bitmap_set(sampass->private.change_flags, element)) { 499 DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); 500 return False; 501 } 502 if (!bitmap_set(sampass->private.set_flags, element)) { 503 DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); 504 return False; 505 } 506 DEBUG(11, ("element %d -> now CHANGED\n", element)); 507 break; 508 case PDB_SET: 509 if (!bitmap_clear(sampass->private.change_flags, element)) { 510 DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); 511 return False; 512 } 513 if (!bitmap_set(sampass->private.set_flags, element)) { 514 DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); 515 return False; 516 } 517 DEBUG(11, ("element %d -> now SET\n", element)); 518 break; 519 case PDB_DEFAULT: 520 default: 521 if (!bitmap_clear(sampass->private.change_flags, element)) { 522 DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); 523 return False; 524 } 525 if (!bitmap_clear(sampass->private.set_flags, element)) { 526 DEBUG(0,("Can't set flag: %d in set_flags.\n",element)); 527 return False; 528 } 529 DEBUG(11, ("element %d -> now DEFAULT\n", element)); 530 break; 531 } 532 533 return True; 534} 535 536BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_value_state flag) 537{ 538 if (!sampass || !u_sid) 539 return False; 540 541 sid_copy(&sampass->private.user_sid, u_sid); 542 543 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 544 sid_string_static(&sampass->private.user_sid))); 545 546 return pdb_set_init_flags(sampass, PDB_USERSID, flag); 547} 548 549BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag) 550{ 551 DOM_SID new_sid; 552 553 if (!sampass || !u_sid) 554 return False; 555 556 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n", 557 u_sid)); 558 559 if (!string_to_sid(&new_sid, u_sid)) { 560 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid)); 561 return False; 562 } 563 564 if (!pdb_set_user_sid(sampass, &new_sid, flag)) { 565 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid)); 566 return False; 567 } 568 569 return True; 570} 571 572BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag) 573{ 574 if (!sampass || !g_sid) 575 return False; 576 577 sid_copy(&sampass->private.group_sid, g_sid); 578 579 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 580 sid_string_static(&sampass->private.group_sid))); 581 582 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag); 583} 584 585BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag) 586{ 587 DOM_SID new_sid; 588 if (!sampass || !g_sid) 589 return False; 590 591 DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n", 592 g_sid)); 593 594 if (!string_to_sid(&new_sid, g_sid)) { 595 DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid)); 596 return False; 597 } 598 599 if (!pdb_set_group_sid(sampass, &new_sid, flag)) { 600 DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid)); 601 return False; 602 } 603 return True; 604} 605 606/********************************************************************* 607 Set the user's UNIX name. 608 ********************************************************************/ 609 610BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag) 611{ 612 if (!sampass) 613 return False; 614 615 if (username) { 616 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username, 617 (sampass->private.username)?(sampass->private.username):"NULL")); 618 619 sampass->private.username = talloc_strdup(sampass->mem_ctx, username); 620 621 if (!sampass->private.username) { 622 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n")); 623 return False; 624 } 625 626 } else { 627 sampass->private.username = PDB_NOT_QUITE_NULL; 628 } 629 630 return pdb_set_init_flags(sampass, PDB_USERNAME, flag); 631} 632 633/********************************************************************* 634 Set the domain name. 635 ********************************************************************/ 636 637BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag) 638{ 639 if (!sampass) 640 return False; 641 642 if (domain) { 643 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain, 644 (sampass->private.domain)?(sampass->private.domain):"NULL")); 645 646 sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain); 647 648 if (!sampass->private.domain) { 649 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n")); 650 return False; 651 } 652 653 } else { 654 sampass->private.domain = PDB_NOT_QUITE_NULL; 655 } 656 657 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag); 658} 659 660/********************************************************************* 661 Set the user's NT name. 662 ********************************************************************/ 663 664BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag) 665{ 666 if (!sampass) 667 return False; 668 669 if (nt_username) { 670 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username, 671 (sampass->private.nt_username)?(sampass->private.nt_username):"NULL")); 672 673 sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username); 674 675 if (!sampass->private.nt_username) { 676 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n")); 677 return False; 678 } 679 680 } else { 681 sampass->private.nt_username = PDB_NOT_QUITE_NULL; 682 } 683 684 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag); 685} 686 687/********************************************************************* 688 Set the user's full name. 689 ********************************************************************/ 690 691BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag) 692{ 693 if (!sampass) 694 return False; 695 696 if (full_name) { 697 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name, 698 (sampass->private.full_name)?(sampass->private.full_name):"NULL")); 699 700 sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name); 701 702 if (!sampass->private.full_name) { 703 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n")); 704 return False; 705 } 706 707 } else { 708 sampass->private.full_name = PDB_NOT_QUITE_NULL; 709 } 710 711 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag); 712} 713 714/********************************************************************* 715 Set the user's logon script. 716 ********************************************************************/ 717 718BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag) 719{ 720 if (!sampass) 721 return False; 722 723 if (logon_script) { 724 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script, 725 (sampass->private.logon_script)?(sampass->private.logon_script):"NULL")); 726 727 sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script); 728 729 if (!sampass->private.logon_script) { 730 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n")); 731 return False; 732 } 733 734 } else { 735 sampass->private.logon_script = PDB_NOT_QUITE_NULL; 736 } 737 738 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag); 739} 740 741/********************************************************************* 742 Set the user's profile path. 743 ********************************************************************/ 744 745BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag) 746{ 747 if (!sampass) 748 return False; 749 750 if (profile_path) { 751 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path, 752 (sampass->private.profile_path)?(sampass->private.profile_path):"NULL")); 753 754 sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path); 755 756 if (!sampass->private.profile_path) { 757 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n")); 758 return False; 759 } 760 761 } else { 762 sampass->private.profile_path = PDB_NOT_QUITE_NULL; 763 } 764 765 return pdb_set_init_flags(sampass, PDB_PROFILE, flag); 766} 767 768/********************************************************************* 769 Set the user's directory drive. 770 ********************************************************************/ 771 772BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag) 773{ 774 if (!sampass) 775 return False; 776 777 if (dir_drive) { 778 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive, 779 (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL")); 780 781 sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive); 782 783 if (!sampass->private.dir_drive) { 784 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n")); 785 return False; 786 } 787 788 } else { 789 sampass->private.dir_drive = PDB_NOT_QUITE_NULL; 790 } 791 792 return pdb_set_init_flags(sampass, PDB_DRIVE, flag); 793} 794 795/********************************************************************* 796 Set the user's home directory. 797 ********************************************************************/ 798 799BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag) 800{ 801 if (!sampass) 802 return False; 803 804 if (home_dir) { 805 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir, 806 (sampass->private.home_dir)?(sampass->private.home_dir):"NULL")); 807 808 sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir); 809 810 if (!sampass->private.home_dir) { 811 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n")); 812 return False; 813 } 814 815 } else { 816 sampass->private.home_dir = PDB_NOT_QUITE_NULL; 817 } 818 819 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag); 820} 821 822/********************************************************************* 823 Set the user's unix home directory. 824 ********************************************************************/ 825 826BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag) 827{ 828 if (!sampass) 829 return False; 830 831 if (unix_home_dir) { 832 DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir, 833 (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL")); 834 835 sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, 836 unix_home_dir); 837 838 if (!sampass->private.unix_home_dir) { 839 DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n")); 840 return False; 841 } 842 843 } else { 844 sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL; 845 } 846 847 return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag); 848} 849 850/********************************************************************* 851 Set the user's account description. 852 ********************************************************************/ 853 854BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag) 855{ 856 if (!sampass) 857 return False; 858 859 if (acct_desc) { 860 sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc); 861 862 if (!sampass->private.acct_desc) { 863 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n")); 864 return False; 865 } 866 867 } else { 868 sampass->private.acct_desc = PDB_NOT_QUITE_NULL; 869 } 870 871 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag); 872} 873 874/********************************************************************* 875 Set the user's workstation allowed list. 876 ********************************************************************/ 877 878BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag) 879{ 880 if (!sampass) 881 return False; 882 883 if (workstations) { 884 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations, 885 (sampass->private.workstations)?(sampass->private.workstations):"NULL")); 886 887 sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations); 888 889 if (!sampass->private.workstations) { 890 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n")); 891 return False; 892 } 893 894 } else { 895 sampass->private.workstations = PDB_NOT_QUITE_NULL; 896 } 897 898 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag); 899} 900 901/********************************************************************* 902 Set the user's 'unknown_str', whatever the heck this actually is... 903 ********************************************************************/ 904 905BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag) 906{ 907 if (!sampass) 908 return False; 909 910 if (unknown_str) { 911 sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str); 912 913 if (!sampass->private.unknown_str) { 914 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); 915 return False; 916 } 917 918 } else { 919 sampass->private.unknown_str = PDB_NOT_QUITE_NULL; 920 } 921 922 return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag); 923} 924 925/********************************************************************* 926 Set the user's dial string. 927 ********************************************************************/ 928 929BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag) 930{ 931 if (!sampass) 932 return False; 933 934 if (munged_dial) { 935 sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial); 936 937 if (!sampass->private.munged_dial) { 938 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n")); 939 return False; 940 } 941 942 } else { 943 sampass->private.munged_dial = PDB_NOT_QUITE_NULL; 944 } 945 946 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag); 947} 948 949/********************************************************************* 950 Set the user's NT hash. 951 ********************************************************************/ 952 953BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag) 954{ 955 if (!sampass) 956 return False; 957 958 data_blob_clear_free(&sampass->private.nt_pw); 959 960 if (pwd) { 961 sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN); 962 } else { 963 sampass->private.nt_pw = data_blob(NULL, 0); 964 } 965 966 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag); 967} 968 969/********************************************************************* 970 Set the user's LM hash. 971 ********************************************************************/ 972 973BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag) 974{ 975 if (!sampass) 976 return False; 977 978 data_blob_clear_free(&sampass->private.lm_pw); 979 980 if (pwd) { 981 sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN); 982 } else { 983 sampass->private.lm_pw = data_blob(NULL, 0); 984 } 985 986 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag); 987} 988 989/********************************************************************* 990 Set the user's password history hash. historyLen is the number of 991 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length 992 entries to store in the history - this must match the size of the uint8 array 993 in pwd. 994********************************************************************/ 995 996BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag) 997{ 998 if (!sampass) 999 return False; 1000 1001 if (historyLen && pwd){ 1002 sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, 1003 pwd, historyLen*PW_HISTORY_ENTRY_LEN); 1004 if (!sampass->private.nt_pw_his.length) { 1005 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n")); 1006 return False; 1007 } 1008 } else { 1009 sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0); 1010 } 1011 1012 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag); 1013} 1014 1015/********************************************************************* 1016 Set the user's plaintext password only (base procedure, see helper 1017 below) 1018 ********************************************************************/ 1019 1020BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag) 1021{ 1022 if (!sampass) 1023 return False; 1024 1025 if (password) { 1026 if (sampass->private.plaintext_pw!=NULL) 1027 memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1); 1028 1029 sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); 1030 1031 if (!sampass->private.plaintext_pw) { 1032 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); 1033 return False; 1034 } 1035 1036 } else { 1037 sampass->private.plaintext_pw = NULL; 1038 } 1039 1040 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag); 1041} 1042 1043BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag) 1044{ 1045 if (!sampass) 1046 return False; 1047 1048 sampass->private.bad_password_count = bad_password_count; 1049 1050 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag); 1051} 1052 1053BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_value_state flag) 1054{ 1055 if (!sampass) 1056 return False; 1057 1058 sampass->private.logon_count = logon_count; 1059 1060 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag); 1061} 1062 1063BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag) 1064{ 1065 if (!sampass) 1066 return False; 1067 1068 sampass->private.unknown_6 = unkn; 1069 1070 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag); 1071} 1072 1073BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag) 1074{ 1075 if (!sampass) 1076 return False; 1077 1078 if (!hours) { 1079 memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN); 1080 return True; 1081 } 1082 1083 memcpy (sampass->private.hours, hours, MAX_HOURS_LEN); 1084 1085 return pdb_set_init_flags(sampass, PDB_HOURS, flag); 1086} 1087 1088BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, 1089 void (*free_fn)(void **), 1090 const struct pdb_methods *my_methods, 1091 enum pdb_value_state flag) 1092{ 1093 if (!sampass) 1094 return False; 1095 1096 if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) { 1097 sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data); 1098 } 1099 1100 sampass->private.backend_private_data = private_data; 1101 sampass->private.backend_private_data_free_fn = free_fn; 1102 sampass->private.backend_private_methods = my_methods; 1103 1104 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag); 1105} 1106 1107 1108/* Helpful interfaces to the above */ 1109 1110/********************************************************************* 1111 Sets the last changed times and must change times for a normal 1112 password change. 1113 ********************************************************************/ 1114 1115BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass) 1116{ 1117 uint32 expire; 1118 uint32 min_age; 1119 1120 if (!sampass) 1121 return False; 1122 1123 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) 1124 return False; 1125 1126 if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) 1127 || (expire==(uint32)-1) || (expire == 0)) { 1128 if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED)) 1129 return False; 1130 } else { 1131 if (!pdb_set_pass_must_change_time (sampass, 1132 pdb_get_pass_last_set_time(sampass) 1133 + expire, PDB_CHANGED)) 1134 return False; 1135 } 1136 1137 if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age) 1138 || (min_age==(uint32)-1)) { 1139 if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED)) 1140 return False; 1141 } else { 1142 if (!pdb_set_pass_can_change_time (sampass, 1143 pdb_get_pass_last_set_time(sampass) 1144 + min_age, PDB_CHANGED)) 1145 return False; 1146 } 1147 return True; 1148} 1149 1150/********************************************************************* 1151 Set the user's PLAINTEXT password. Used as an interface to the above. 1152 Also sets the last change time to NOW. 1153 ********************************************************************/ 1154 1155BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) 1156{ 1157 uchar new_lanman_p16[LM_HASH_LEN]; 1158 uchar new_nt_p16[NT_HASH_LEN]; 1159 1160 if (!sampass || !plaintext) 1161 return False; 1162 1163 /* Calculate the MD4 hash (NT compatible) of the password */ 1164 E_md4hash(plaintext, new_nt_p16); 1165 1166 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 1167 return False; 1168 1169 if (!E_deshash(plaintext, new_lanman_p16)) { 1170 /* E_deshash returns false for 'long' passwords (> 14 1171 DOS chars). This allows us to match Win2k, which 1172 does not store a LM hash for these passwords (which 1173 would reduce the effective password length to 14 */ 1174 1175 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) 1176 return False; 1177 } else { 1178 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 1179 return False; 1180 } 1181 1182 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 1183 return False; 1184 1185 if (!pdb_set_pass_changed_now (sampass)) 1186 return False; 1187 1188 /* Store the password history. */ 1189 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) { 1190 uchar *pwhistory; 1191 uint32 pwHistLen; 1192 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen); 1193 if (pwHistLen != 0){ 1194 uint32 current_history_len; 1195 /* We need to make sure we don't have a race condition here - the 1196 account policy history length can change between when the pw_history 1197 was first loaded into the SAM_ACCOUNT struct and now.... JRA. */ 1198 pwhistory = (uchar *)pdb_get_pw_history(sampass, ¤t_history_len); 1199 1200 if (current_history_len != pwHistLen) { 1201 /* After closing and reopening SAM_ACCOUNT the history 1202 values will sync up. We can't do this here. */ 1203 1204 /* current_history_len > pwHistLen is not a problem - we 1205 have more history than we need. */ 1206 1207 if (current_history_len < pwHistLen) { 1208 /* Ensure we have space for the needed history. */ 1209 uchar *new_history = TALLOC(sampass->mem_ctx, 1210 pwHistLen*PW_HISTORY_ENTRY_LEN); 1211 /* And copy it into the new buffer. */ 1212 if (current_history_len) { 1213 memcpy(new_history, pwhistory, 1214 current_history_len*PW_HISTORY_ENTRY_LEN); 1215 } 1216 /* Clearing out any extra space. */ 1217 memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN], 1218 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN); 1219 /* Finally replace it. */ 1220 pwhistory = new_history; 1221 } 1222 } 1223 if (pwhistory && pwHistLen){ 1224 /* Make room for the new password in the history list. */ 1225 if (pwHistLen > 1) { 1226 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], 1227 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN ); 1228 } 1229 /* Create the new salt as the first part of the history entry. */ 1230 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN); 1231 1232 /* Generate the md5 hash of the salt+new password as the second 1233 part of the history entry. */ 1234 1235 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]); 1236 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); 1237 } else { 1238 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n")); 1239 } 1240 } else { 1241 /* Set the history length to zero. */ 1242 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED); 1243 } 1244 } 1245 1246 return True; 1247} 1248 1249/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */ 1250uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass) 1251{ 1252 /* value set to all for testing */ 1253 return 0x00ffffff; 1254} 1255