1/* 2 Unix SMB/CIFS implementation. 3 Password and authentication handling 4 Copyright (C) Jeremy Allison 1996-2001 5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 6 Copyright (C) Gerald (Jerry) Carter 2000-2006 7 Copyright (C) Andrew Bartlett 2001-2002 8 Copyright (C) Simo Sorce 2003 9 Copyright (C) Volker Lendecke 2006 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23*/ 24 25#include "includes.h" 26#include "../libcli/auth/libcli_auth.h" 27 28#undef DBGC_CLASS 29#define DBGC_CLASS DBGC_PASSDB 30 31/****************************************************************** 32 Get the default domain/netbios name to be used when 33 testing authentication. 34 35 LEGACY: this function provides the legacy domain mapping used with 36 the lp_map_untrusted_to_domain() parameter 37******************************************************************/ 38 39const char *my_sam_name(void) 40{ 41 /* Standalone servers can only use the local netbios name */ 42 if ( lp_server_role() == ROLE_STANDALONE ) 43 return global_myname(); 44 45 /* Default to the DOMAIN name when not specified */ 46 return lp_workgroup(); 47} 48 49/********************************************************************** 50***********************************************************************/ 51 52static int samu_destroy(struct samu *user) 53{ 54 data_blob_clear_free( &user->lm_pw ); 55 data_blob_clear_free( &user->nt_pw ); 56 57 if ( user->plaintext_pw ) 58 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) ); 59 60 return 0; 61} 62 63/********************************************************************** 64 generate a new struct samuser 65***********************************************************************/ 66 67struct samu *samu_new( TALLOC_CTX *ctx ) 68{ 69 struct samu *user; 70 71 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) { 72 DEBUG(0,("samuser_new: Talloc failed!\n")); 73 return NULL; 74 } 75 76 talloc_set_destructor( user, samu_destroy ); 77 78 /* no initial methods */ 79 80 user->methods = NULL; 81 82 /* Don't change these timestamp settings without a good reason. 83 They are important for NT member server compatibility. */ 84 85 user->logon_time = (time_t)0; 86 user->pass_last_set_time = (time_t)0; 87 user->pass_can_change_time = (time_t)0; 88 user->logoff_time = get_time_t_max(); 89 user->kickoff_time = get_time_t_max(); 90 user->pass_must_change_time = get_time_t_max(); 91 user->fields_present = 0x00ffffff; 92 user->logon_divs = 168; /* hours per week */ 93 user->hours_len = 21; /* 21 times 8 bits = 168 */ 94 memset(user->hours, 0xff, user->hours_len); /* available at all hours */ 95 user->bad_password_count = 0; 96 user->logon_count = 0; 97 user->unknown_6 = 0x000004ec; /* don't know */ 98 99 /* Some parts of samba strlen their pdb_get...() returns, 100 so this keeps the interface unchanged for now. */ 101 102 user->username = ""; 103 user->domain = ""; 104 user->nt_username = ""; 105 user->full_name = ""; 106 user->home_dir = ""; 107 user->logon_script = ""; 108 user->profile_path = ""; 109 user->acct_desc = ""; 110 user->workstations = ""; 111 user->comment = ""; 112 user->munged_dial = ""; 113 114 user->plaintext_pw = NULL; 115 116 /* Unless we know otherwise have a Account Control Bit 117 value of 'normal user'. This helps User Manager, which 118 asks for a filtered list of users. */ 119 120 user->acct_ctrl = ACB_NORMAL; 121 122 return user; 123} 124 125static int count_commas(const char *str) 126{ 127 int num_commas = 0; 128 const char *comma = str; 129 130 while ((comma = strchr(comma, ',')) != NULL) { 131 comma += 1; 132 num_commas += 1; 133 } 134 return num_commas; 135} 136 137/********************************************************************* 138 Initialize a struct samu from a struct passwd including the user 139 and group SIDs. The *user structure is filled out with the Unix 140 attributes and a user SID. 141*********************************************************************/ 142 143static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create) 144{ 145 const char *guest_account = lp_guestaccount(); 146 const char *domain = global_myname(); 147 char *fullname; 148 uint32 urid; 149 150 if ( !pwd ) { 151 return NT_STATUS_NO_SUCH_USER; 152 } 153 154 /* Basic properties based upon the Unix account information */ 155 156 pdb_set_username(user, pwd->pw_name, PDB_SET); 157 158 fullname = NULL; 159 160 if (count_commas(pwd->pw_gecos) == 3) { 161 /* 162 * Heuristic: This seems to be a gecos field that has been 163 * edited by chfn(1). Only use the part before the first 164 * comma. Fixes bug 5198. 165 */ 166 fullname = talloc_strndup( 167 talloc_tos(), pwd->pw_gecos, 168 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos); 169 } 170 171 if (fullname != NULL) { 172 pdb_set_fullname(user, fullname, PDB_SET); 173 } else { 174 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET); 175 } 176 TALLOC_FREE(fullname); 177 178 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT); 179#if 0 180 /* This can lead to a primary group of S-1-22-2-XX which 181 will be rejected by other parts of the Samba code. 182 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM) 183 --jerry */ 184 185 gid_to_sid(&group_sid, pwd->pw_gid); 186 pdb_set_group_sid(user, &group_sid, PDB_SET); 187#endif 188 189 /* save the password structure for later use */ 190 191 user->unix_pw = tcopy_passwd( user, pwd ); 192 193 /* Special case for the guest account which must have a RID of 501 */ 194 195 if ( strequal( pwd->pw_name, guest_account ) ) { 196 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { 197 return NT_STATUS_NO_SUCH_USER; 198 } 199 return NT_STATUS_OK; 200 } 201 202 /* Non-guest accounts...Check for a workstation or user account */ 203 204 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') { 205 /* workstation */ 206 207 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) { 208 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n", 209 pwd->pw_name)); 210 return NT_STATUS_INVALID_COMPUTER_NAME; 211 } 212 } 213 else { 214 /* user */ 215 216 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) { 217 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", 218 pwd->pw_name)); 219 return NT_STATUS_INVALID_ACCOUNT_NAME; 220 } 221 222 /* set some basic attributes */ 223 224 pdb_set_profile_path(user, talloc_sub_specified(user, 225 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 226 PDB_DEFAULT); 227 pdb_set_homedir(user, talloc_sub_specified(user, 228 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 229 PDB_DEFAULT); 230 pdb_set_dir_drive(user, talloc_sub_specified(user, 231 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 232 PDB_DEFAULT); 233 pdb_set_logon_script(user, talloc_sub_specified(user, 234 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 235 PDB_DEFAULT); 236 } 237 238 /* Now deal with the user SID. If we have a backend that can generate 239 RIDs, then do so. But sometimes the caller just wanted a structure 240 initialized and will fill in these fields later (such as from a 241 netr_SamInfo3 structure) */ 242 243 if ( create && (pdb_capabilities() & PDB_CAP_STORE_RIDS)) { 244 uint32 user_rid; 245 DOM_SID user_sid; 246 247 if ( !pdb_new_rid( &user_rid ) ) { 248 DEBUG(3, ("Could not allocate a new RID\n")); 249 return NT_STATUS_ACCESS_DENIED; 250 } 251 252 sid_copy( &user_sid, get_global_sam_sid() ); 253 sid_append_rid( &user_sid, user_rid ); 254 255 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) { 256 DEBUG(3, ("pdb_set_user_sid failed\n")); 257 return NT_STATUS_INTERNAL_ERROR; 258 } 259 260 return NT_STATUS_OK; 261 } 262 263 /* generate a SID for the user with the RID algorithm */ 264 265 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid ); 266 267 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) { 268 return NT_STATUS_INTERNAL_ERROR; 269 } 270 271 return NT_STATUS_OK; 272} 273 274/******************************************************************** 275 Set the Unix user attributes 276********************************************************************/ 277 278NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd) 279{ 280 return samu_set_unix_internal( user, pwd, False ); 281} 282 283NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd) 284{ 285 return samu_set_unix_internal( user, pwd, True ); 286} 287 288/********************************************************** 289 Encode the account control bits into a string. 290 length = length of string to encode into (including terminating 291 null). length *MUST BE MORE THAN 2* ! 292 **********************************************************/ 293 294char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length) 295{ 296 fstring acct_str; 297 char *result; 298 299 size_t i = 0; 300 301 SMB_ASSERT(length <= sizeof(acct_str)); 302 303 acct_str[i++] = '['; 304 305 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; 306 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D'; 307 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H'; 308 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T'; 309 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U'; 310 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M'; 311 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W'; 312 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S'; 313 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L'; 314 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X'; 315 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I'; 316 317 for ( ; i < length - 2 ; i++ ) 318 acct_str[i] = ' '; 319 320 i = length - 2; 321 acct_str[i++] = ']'; 322 acct_str[i++] = '\0'; 323 324 result = talloc_strdup(talloc_tos(), acct_str); 325 SMB_ASSERT(result != NULL); 326 return result; 327} 328 329/********************************************************** 330 Decode the account control bits from a string. 331 **********************************************************/ 332 333uint32_t pdb_decode_acct_ctrl(const char *p) 334{ 335 uint32_t acct_ctrl = 0; 336 bool finished = false; 337 338 /* 339 * Check if the account type bits have been encoded after the 340 * NT password (in the form [NDHTUWSLXI]). 341 */ 342 343 if (*p != '[') 344 return 0; 345 346 for (p++; *p && !finished; p++) { 347 switch (*p) { 348 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } 349 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } 350 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ } 351 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ } 352 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ } 353 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ } 354 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ } 355 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 356 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 357 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } 358 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } 359 case ' ': { break; } 360 case ':': 361 case '\n': 362 case '\0': 363 case ']': 364 default: { finished = true; } 365 } 366 } 367 368 return acct_ctrl; 369} 370 371/************************************************************* 372 Routine to set 32 hex password characters from a 16 byte array. 373**************************************************************/ 374 375void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32 acct_ctrl) 376{ 377 if (pwd != NULL) { 378 int i; 379 for (i = 0; i < 16; i++) 380 slprintf(&p[i*2], 3, "%02X", pwd[i]); 381 } else { 382 if (acct_ctrl & ACB_PWNOTREQ) 383 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32); 384 else 385 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32); 386 } 387} 388 389/************************************************************* 390 Routine to get the 32 hex characters and turn them 391 into a 16 byte array. 392**************************************************************/ 393 394bool pdb_gethexpwd(const char *p, unsigned char *pwd) 395{ 396 int i; 397 unsigned char lonybble, hinybble; 398 const char *hexchars = "0123456789ABCDEF"; 399 char *p1, *p2; 400 401 if (!p) 402 return false; 403 404 for (i = 0; i < 32; i += 2) { 405 hinybble = toupper_ascii(p[i]); 406 lonybble = toupper_ascii(p[i + 1]); 407 408 p1 = strchr(hexchars, hinybble); 409 p2 = strchr(hexchars, lonybble); 410 411 if (!p1 || !p2) 412 return false; 413 414 hinybble = PTR_DIFF(p1, hexchars); 415 lonybble = PTR_DIFF(p2, hexchars); 416 417 pwd[i / 2] = (hinybble << 4) | lonybble; 418 } 419 return true; 420} 421 422/************************************************************* 423 Routine to set 42 hex hours characters from a 21 byte array. 424**************************************************************/ 425 426void pdb_sethexhours(char *p, const unsigned char *hours) 427{ 428 if (hours != NULL) { 429 int i; 430 for (i = 0; i < 21; i++) { 431 slprintf(&p[i*2], 3, "%02X", hours[i]); 432 } 433 } else { 434 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43); 435 } 436} 437 438/************************************************************* 439 Routine to get the 42 hex characters and turn them 440 into a 21 byte array. 441**************************************************************/ 442 443bool pdb_gethexhours(const char *p, unsigned char *hours) 444{ 445 int i; 446 unsigned char lonybble, hinybble; 447 const char *hexchars = "0123456789ABCDEF"; 448 char *p1, *p2; 449 450 if (!p) { 451 return (False); 452 } 453 454 for (i = 0; i < 42; i += 2) { 455 hinybble = toupper_ascii(p[i]); 456 lonybble = toupper_ascii(p[i + 1]); 457 458 p1 = strchr(hexchars, hinybble); 459 p2 = strchr(hexchars, lonybble); 460 461 if (!p1 || !p2) { 462 return (False); 463 } 464 465 hinybble = PTR_DIFF(p1, hexchars); 466 lonybble = PTR_DIFF(p2, hexchars); 467 468 hours[i / 2] = (hinybble << 4) | lonybble; 469 } 470 return (True); 471} 472 473/******************************************************************** 474********************************************************************/ 475 476int algorithmic_rid_base(void) 477{ 478 int rid_offset; 479 480 rid_offset = lp_algorithmic_rid_base(); 481 482 if (rid_offset < BASE_RID) { 483 /* Try to prevent admin foot-shooting, we can't put algorithmic 484 rids below 1000, that's the 'well known RIDs' on NT */ 485 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID)); 486 rid_offset = BASE_RID; 487 } 488 if (rid_offset & 1) { 489 DEBUG(0, ("algorithmic rid base must be even\n")); 490 rid_offset += 1; 491 } 492 return rid_offset; 493} 494 495/******************************************************************* 496 Converts NT user RID to a UNIX uid. 497 ********************************************************************/ 498 499uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid) 500{ 501 int rid_offset = algorithmic_rid_base(); 502 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER); 503} 504 505uid_t max_algorithmic_uid(void) 506{ 507 return algorithmic_pdb_user_rid_to_uid(0xfffffffe); 508} 509 510/******************************************************************* 511 converts UNIX uid to an NT User RID. 512 ********************************************************************/ 513 514uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid) 515{ 516 int rid_offset = algorithmic_rid_base(); 517 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE); 518} 519 520/******************************************************************* 521 Converts NT group RID to a UNIX gid. 522 ********************************************************************/ 523 524gid_t pdb_group_rid_to_gid(uint32 group_rid) 525{ 526 int rid_offset = algorithmic_rid_base(); 527 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER); 528} 529 530gid_t max_algorithmic_gid(void) 531{ 532 return pdb_group_rid_to_gid(0xffffffff); 533} 534 535/******************************************************************* 536 converts NT Group RID to a UNIX uid. 537 538 warning: you must not call that function only 539 you must do a call to the group mapping first. 540 there is not anymore a direct link between the gid and the rid. 541 ********************************************************************/ 542 543uint32 algorithmic_pdb_gid_to_group_rid(gid_t gid) 544{ 545 int rid_offset = algorithmic_rid_base(); 546 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE); 547} 548 549/******************************************************************* 550 Decides if a RID is a well known RID. 551 ********************************************************************/ 552 553static bool rid_is_well_known(uint32 rid) 554{ 555 /* Not using rid_offset here, because this is the actual 556 NT fixed value (1000) */ 557 558 return (rid < BASE_RID); 559} 560 561/******************************************************************* 562 Decides if a RID is a user or group RID. 563 ********************************************************************/ 564 565bool algorithmic_pdb_rid_is_user(uint32 rid) 566{ 567 if ( rid_is_well_known(rid) ) { 568 /* 569 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN 570 * and DOMAIN_USER_RID_GUEST. 571 */ 572 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST) 573 return True; 574 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) { 575 return True; 576 } 577 return False; 578} 579 580/******************************************************************* 581 Convert a name into a SID. Used in the lookup name rpc. 582 ********************************************************************/ 583 584bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid, 585 enum lsa_SidType *type) 586{ 587 GROUP_MAP map; 588 bool ret; 589 590 /* Windows treats "MACHINE\None" as a special name for 591 rid 513 on non-DCs. You cannot create a user or group 592 name "None" on Windows. You will get an error that 593 the group already exists. */ 594 595 if ( strequal( name, "None" ) ) { 596 *rid = DOMAIN_GROUP_RID_USERS; 597 *type = SID_NAME_DOM_GRP; 598 599 return True; 600 } 601 602 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work 603 * correctly in the case where foo also exists as a user. If the flag 604 * is set, don't look for users at all. */ 605 606 if ((flags & LOOKUP_NAME_GROUP) == 0) { 607 struct samu *sam_account = NULL; 608 DOM_SID user_sid; 609 610 if ( !(sam_account = samu_new( NULL )) ) { 611 return False; 612 } 613 614 become_root(); 615 ret = pdb_getsampwnam(sam_account, name); 616 unbecome_root(); 617 618 if (ret) { 619 sid_copy(&user_sid, pdb_get_user_sid(sam_account)); 620 } 621 622 TALLOC_FREE(sam_account); 623 624 if (ret) { 625 if (!sid_check_is_in_our_domain(&user_sid)) { 626 DEBUG(0, ("User %s with invalid SID %s in passdb\n", 627 name, sid_string_dbg(&user_sid))); 628 return False; 629 } 630 631 sid_peek_rid(&user_sid, rid); 632 *type = SID_NAME_USER; 633 return True; 634 } 635 } 636 637 /* 638 * Maybe it is a group ? 639 */ 640 641 become_root(); 642 ret = pdb_getgrnam(&map, name); 643 unbecome_root(); 644 645 if (!ret) { 646 return False; 647 } 648 649 /* BUILTIN groups are looked up elsewhere */ 650 if (!sid_check_is_in_our_domain(&map.sid)) { 651 DEBUG(10, ("Found group %s (%s) not in our domain -- " 652 "ignoring.", name, sid_string_dbg(&map.sid))); 653 return False; 654 } 655 656 /* yes it's a mapped group */ 657 sid_peek_rid(&map.sid, rid); 658 *type = map.sid_name_use; 659 return True; 660} 661 662/************************************************************* 663 Change a password entry in the local passdb backend. 664 665 Assumptions: 666 - always called as root 667 - ignores the account type except when adding a new account 668 - will create/delete the unix account if the relative 669 add/delete user script is configured 670 671 *************************************************************/ 672 673NTSTATUS local_password_change(const char *user_name, 674 int local_flags, 675 const char *new_passwd, 676 char **pp_err_str, 677 char **pp_msg_str) 678{ 679 TALLOC_CTX *tosctx; 680 struct samu *sam_pass; 681 uint32_t acb; 682 uint32_t rid; 683 NTSTATUS result; 684 bool user_exists; 685 int ret = -1; 686 687 *pp_err_str = NULL; 688 *pp_msg_str = NULL; 689 690 tosctx = talloc_tos(); 691 692 sam_pass = samu_new(tosctx); 693 if (!sam_pass) { 694 result = NT_STATUS_NO_MEMORY; 695 goto done; 696 } 697 698 /* Get the smb passwd entry for this user */ 699 user_exists = pdb_getsampwnam(sam_pass, user_name); 700 701 /* Check delete first, we don't need to do anything else if we 702 * are going to delete the acocunt */ 703 if (user_exists && (local_flags & LOCAL_DELETE_USER)) { 704 705 result = pdb_delete_user(tosctx, sam_pass); 706 if (!NT_STATUS_IS_OK(result)) { 707 ret = asprintf(pp_err_str, 708 "Failed to delete entry for user %s.\n", 709 user_name); 710 if (ret < 0) { 711 *pp_err_str = NULL; 712 } 713 result = NT_STATUS_UNSUCCESSFUL; 714 } else { 715 ret = asprintf(pp_msg_str, 716 "Deleted user %s.\n", 717 user_name); 718 if (ret < 0) { 719 *pp_msg_str = NULL; 720 } 721 } 722 goto done; 723 } 724 725 if (user_exists && (local_flags & LOCAL_ADD_USER)) { 726 /* the entry already existed */ 727 local_flags &= ~LOCAL_ADD_USER; 728 } 729 730 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) { 731 ret = asprintf(pp_err_str, 732 "Failed to find entry for user %s.\n", 733 user_name); 734 if (ret < 0) { 735 *pp_err_str = NULL; 736 } 737 result = NT_STATUS_NO_SUCH_USER; 738 goto done; 739 } 740 741 /* First thing add the new user if we are required to do so */ 742 if (local_flags & LOCAL_ADD_USER) { 743 744 if (local_flags & LOCAL_TRUST_ACCOUNT) { 745 acb = ACB_WSTRUST; 746 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { 747 acb = ACB_DOMTRUST; 748 } else { 749 acb = ACB_NORMAL; 750 } 751 752 result = pdb_create_user(tosctx, user_name, acb, &rid); 753 if (!NT_STATUS_IS_OK(result)) { 754 ret = asprintf(pp_err_str, 755 "Failed to add entry for user %s.\n", 756 user_name); 757 if (ret < 0) { 758 *pp_err_str = NULL; 759 } 760 result = NT_STATUS_UNSUCCESSFUL; 761 goto done; 762 } 763 764 sam_pass = samu_new(tosctx); 765 if (!sam_pass) { 766 result = NT_STATUS_NO_MEMORY; 767 goto done; 768 } 769 770 /* Now get back the smb passwd entry for this new user */ 771 user_exists = pdb_getsampwnam(sam_pass, user_name); 772 if (!user_exists) { 773 ret = asprintf(pp_err_str, 774 "Failed to add entry for user %s.\n", 775 user_name); 776 if (ret < 0) { 777 *pp_err_str = NULL; 778 } 779 result = NT_STATUS_UNSUCCESSFUL; 780 goto done; 781 } 782 } 783 784 acb = pdb_get_acct_ctrl(sam_pass); 785 786 /* 787 * We are root - just write the new password 788 * and the valid last change time. 789 */ 790 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) { 791 acb |= ACB_PWNOTREQ; 792 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { 793 ret = asprintf(pp_err_str, 794 "Failed to set 'no password required' " 795 "flag for user %s.\n", user_name); 796 if (ret < 0) { 797 *pp_err_str = NULL; 798 } 799 result = NT_STATUS_UNSUCCESSFUL; 800 goto done; 801 } 802 } 803 804 if (local_flags & LOCAL_SET_PASSWORD) { 805 /* 806 * If we're dealing with setting a completely empty user account 807 * ie. One with a password of 'XXXX', but not set disabled (like 808 * an account created from scratch) then if the old password was 809 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag. 810 * We remove that as we're giving this user their first password 811 * and the decision hasn't really been made to disable them (ie. 812 * don't create them disabled). JRA. 813 */ 814 if ((pdb_get_lanman_passwd(sam_pass) == NULL) && 815 (acb & ACB_DISABLED)) { 816 acb &= (~ACB_DISABLED); 817 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { 818 ret = asprintf(pp_err_str, 819 "Failed to unset 'disabled' " 820 "flag for user %s.\n", 821 user_name); 822 if (ret < 0) { 823 *pp_err_str = NULL; 824 } 825 result = NT_STATUS_UNSUCCESSFUL; 826 goto done; 827 } 828 } 829 830 acb &= (~ACB_PWNOTREQ); 831 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { 832 ret = asprintf(pp_err_str, 833 "Failed to unset 'no password required'" 834 " flag for user %s.\n", user_name); 835 if (ret < 0) { 836 *pp_err_str = NULL; 837 } 838 result = NT_STATUS_UNSUCCESSFUL; 839 goto done; 840 } 841 842 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) { 843 ret = asprintf(pp_err_str, 844 "Failed to set password for " 845 "user %s.\n", user_name); 846 if (ret < 0) { 847 *pp_err_str = NULL; 848 } 849 result = NT_STATUS_UNSUCCESSFUL; 850 goto done; 851 } 852 } 853 854 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) { 855 acb |= ACB_DISABLED; 856 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { 857 ret = asprintf(pp_err_str, 858 "Failed to set 'disabled' flag for " 859 "user %s.\n", user_name); 860 if (ret < 0) { 861 *pp_err_str = NULL; 862 } 863 result = NT_STATUS_UNSUCCESSFUL; 864 goto done; 865 } 866 } 867 868 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) { 869 acb &= (~ACB_DISABLED); 870 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { 871 ret = asprintf(pp_err_str, 872 "Failed to unset 'disabled' flag for " 873 "user %s.\n", user_name); 874 if (ret < 0) { 875 *pp_err_str = NULL; 876 } 877 result = NT_STATUS_UNSUCCESSFUL; 878 goto done; 879 } 880 } 881 882 /* now commit changes if any */ 883 result = pdb_update_sam_account(sam_pass); 884 if (!NT_STATUS_IS_OK(result)) { 885 ret = asprintf(pp_err_str, 886 "Failed to modify entry for user %s.\n", 887 user_name); 888 if (ret < 0) { 889 *pp_err_str = NULL; 890 } 891 goto done; 892 } 893 894 if (local_flags & LOCAL_ADD_USER) { 895 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name); 896 } else if (local_flags & LOCAL_DISABLE_USER) { 897 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name); 898 } else if (local_flags & LOCAL_ENABLE_USER) { 899 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name); 900 } else if (local_flags & LOCAL_SET_NO_PASSWORD) { 901 ret = asprintf(pp_msg_str, 902 "User %s password set to none.\n", user_name); 903 } 904 905 if (ret < 0) { 906 *pp_msg_str = NULL; 907 } 908 909 result = NT_STATUS_OK; 910 911done: 912 TALLOC_FREE(sam_pass); 913 return result; 914} 915 916/********************************************************************** 917 Marshall/unmarshall struct samu structs. 918 *********************************************************************/ 919 920#define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" 921#define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" 922#define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" 923#define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" 924/* nothing changed between V3 and V4 */ 925 926/********************************************************************* 927*********************************************************************/ 928 929static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen) 930{ 931 932 /* times are stored as 32bit integer 933 take care on system with 64bit wide time_t 934 --SSS */ 935 uint32 logon_time, 936 logoff_time, 937 kickoff_time, 938 pass_last_set_time, 939 pass_can_change_time, 940 pass_must_change_time; 941 char *username = NULL; 942 char *domain = NULL; 943 char *nt_username = NULL; 944 char *dir_drive = NULL; 945 char *unknown_str = NULL; 946 char *munged_dial = NULL; 947 char *fullname = NULL; 948 char *homedir = NULL; 949 char *logon_script = NULL; 950 char *profile_path = NULL; 951 char *acct_desc = NULL; 952 char *workstations = NULL; 953 uint32 username_len, domain_len, nt_username_len, 954 dir_drive_len, unknown_str_len, munged_dial_len, 955 fullname_len, homedir_len, logon_script_len, 956 profile_path_len, acct_desc_len, workstations_len; 957 958 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; 959 uint16 acct_ctrl, logon_divs; 960 uint16 bad_password_count, logon_count; 961 uint8 *hours = NULL; 962 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL; 963 uint32 len = 0; 964 uint32 lm_pw_len, nt_pw_len, hourslen; 965 bool ret = True; 966 967 if(sampass == NULL || buf == NULL) { 968 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n")); 969 return False; 970 } 971 972/* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */ 973 974 /* unpack the buffer into variables */ 975 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0, 976 &logon_time, /* d */ 977 &logoff_time, /* d */ 978 &kickoff_time, /* d */ 979 &pass_last_set_time, /* d */ 980 &pass_can_change_time, /* d */ 981 &pass_must_change_time, /* d */ 982 &username_len, &username, /* B */ 983 &domain_len, &domain, /* B */ 984 &nt_username_len, &nt_username, /* B */ 985 &fullname_len, &fullname, /* B */ 986 &homedir_len, &homedir, /* B */ 987 &dir_drive_len, &dir_drive, /* B */ 988 &logon_script_len, &logon_script, /* B */ 989 &profile_path_len, &profile_path, /* B */ 990 &acct_desc_len, &acct_desc, /* B */ 991 &workstations_len, &workstations, /* B */ 992 &unknown_str_len, &unknown_str, /* B */ 993 &munged_dial_len, &munged_dial, /* B */ 994 &user_rid, /* d */ 995 &group_rid, /* d */ 996 &lm_pw_len, &lm_pw_ptr, /* B */ 997 &nt_pw_len, &nt_pw_ptr, /* B */ 998 &acct_ctrl, /* w */ 999 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */ 1000 &logon_divs, /* w */ 1001 &hours_len, /* d */ 1002 &hourslen, &hours, /* B */ 1003 &bad_password_count, /* w */ 1004 &logon_count, /* w */ 1005 &unknown_6); /* d */ 1006 1007 if (len == (uint32) -1) { 1008 ret = False; 1009 goto done; 1010 } 1011 1012 pdb_set_logon_time(sampass, logon_time, PDB_SET); 1013 pdb_set_logoff_time(sampass, logoff_time, PDB_SET); 1014 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); 1015 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); 1016 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); 1017 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); 1018 1019 pdb_set_username(sampass, username, PDB_SET); 1020 pdb_set_domain(sampass, domain, PDB_SET); 1021 pdb_set_nt_username(sampass, nt_username, PDB_SET); 1022 pdb_set_fullname(sampass, fullname, PDB_SET); 1023 1024 if (homedir) { 1025 pdb_set_homedir(sampass, homedir, PDB_SET); 1026 } 1027 else { 1028 pdb_set_homedir(sampass, 1029 talloc_sub_basic(sampass, username, domain, 1030 lp_logon_home()), 1031 PDB_DEFAULT); 1032 } 1033 1034 if (dir_drive) 1035 pdb_set_dir_drive(sampass, dir_drive, PDB_SET); 1036 else { 1037 pdb_set_dir_drive(sampass, 1038 talloc_sub_basic(sampass, username, domain, 1039 lp_logon_drive()), 1040 PDB_DEFAULT); 1041 } 1042 1043 if (logon_script) 1044 pdb_set_logon_script(sampass, logon_script, PDB_SET); 1045 else { 1046 pdb_set_logon_script(sampass, 1047 talloc_sub_basic(sampass, username, domain, 1048 lp_logon_script()), 1049 PDB_DEFAULT); 1050 } 1051 1052 if (profile_path) { 1053 pdb_set_profile_path(sampass, profile_path, PDB_SET); 1054 } else { 1055 pdb_set_profile_path(sampass, 1056 talloc_sub_basic(sampass, username, domain, 1057 lp_logon_path()), 1058 PDB_DEFAULT); 1059 } 1060 1061 pdb_set_acct_desc(sampass, acct_desc, PDB_SET); 1062 pdb_set_workstations(sampass, workstations, PDB_SET); 1063 pdb_set_munged_dial(sampass, munged_dial, PDB_SET); 1064 1065 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { 1066 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { 1067 ret = False; 1068 goto done; 1069 } 1070 } 1071 1072 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { 1073 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { 1074 ret = False; 1075 goto done; 1076 } 1077 } 1078 1079 pdb_set_pw_history(sampass, NULL, 0, PDB_SET); 1080 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); 1081 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); 1082 pdb_set_hours_len(sampass, hours_len, PDB_SET); 1083 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); 1084 pdb_set_logon_count(sampass, logon_count, PDB_SET); 1085 pdb_set_unknown_6(sampass, unknown_6, PDB_SET); 1086 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); 1087 pdb_set_logon_divs(sampass, logon_divs, PDB_SET); 1088 pdb_set_hours(sampass, hours, PDB_SET); 1089 1090done: 1091 1092 SAFE_FREE(username); 1093 SAFE_FREE(domain); 1094 SAFE_FREE(nt_username); 1095 SAFE_FREE(fullname); 1096 SAFE_FREE(homedir); 1097 SAFE_FREE(dir_drive); 1098 SAFE_FREE(logon_script); 1099 SAFE_FREE(profile_path); 1100 SAFE_FREE(acct_desc); 1101 SAFE_FREE(workstations); 1102 SAFE_FREE(munged_dial); 1103 SAFE_FREE(unknown_str); 1104 SAFE_FREE(lm_pw_ptr); 1105 SAFE_FREE(nt_pw_ptr); 1106 SAFE_FREE(hours); 1107 1108 return ret; 1109} 1110 1111/********************************************************************* 1112*********************************************************************/ 1113 1114static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen) 1115{ 1116 1117 /* times are stored as 32bit integer 1118 take care on system with 64bit wide time_t 1119 --SSS */ 1120 uint32 logon_time, 1121 logoff_time, 1122 kickoff_time, 1123 bad_password_time, 1124 pass_last_set_time, 1125 pass_can_change_time, 1126 pass_must_change_time; 1127 char *username = NULL; 1128 char *domain = NULL; 1129 char *nt_username = NULL; 1130 char *dir_drive = NULL; 1131 char *unknown_str = NULL; 1132 char *munged_dial = NULL; 1133 char *fullname = NULL; 1134 char *homedir = NULL; 1135 char *logon_script = NULL; 1136 char *profile_path = NULL; 1137 char *acct_desc = NULL; 1138 char *workstations = NULL; 1139 uint32 username_len, domain_len, nt_username_len, 1140 dir_drive_len, unknown_str_len, munged_dial_len, 1141 fullname_len, homedir_len, logon_script_len, 1142 profile_path_len, acct_desc_len, workstations_len; 1143 1144 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; 1145 uint16 acct_ctrl, logon_divs; 1146 uint16 bad_password_count, logon_count; 1147 uint8 *hours = NULL; 1148 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL; 1149 uint32 len = 0; 1150 uint32 lm_pw_len, nt_pw_len, hourslen; 1151 bool ret = True; 1152 1153 if(sampass == NULL || buf == NULL) { 1154 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n")); 1155 return False; 1156 } 1157 1158/* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */ 1159 1160 /* unpack the buffer into variables */ 1161 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1, 1162 &logon_time, /* d */ 1163 &logoff_time, /* d */ 1164 &kickoff_time, /* d */ 1165 /* Change from V0 is addition of bad_password_time field. */ 1166 &bad_password_time, /* d */ 1167 &pass_last_set_time, /* d */ 1168 &pass_can_change_time, /* d */ 1169 &pass_must_change_time, /* d */ 1170 &username_len, &username, /* B */ 1171 &domain_len, &domain, /* B */ 1172 &nt_username_len, &nt_username, /* B */ 1173 &fullname_len, &fullname, /* B */ 1174 &homedir_len, &homedir, /* B */ 1175 &dir_drive_len, &dir_drive, /* B */ 1176 &logon_script_len, &logon_script, /* B */ 1177 &profile_path_len, &profile_path, /* B */ 1178 &acct_desc_len, &acct_desc, /* B */ 1179 &workstations_len, &workstations, /* B */ 1180 &unknown_str_len, &unknown_str, /* B */ 1181 &munged_dial_len, &munged_dial, /* B */ 1182 &user_rid, /* d */ 1183 &group_rid, /* d */ 1184 &lm_pw_len, &lm_pw_ptr, /* B */ 1185 &nt_pw_len, &nt_pw_ptr, /* B */ 1186 &acct_ctrl, /* w */ 1187 &remove_me, /* d */ 1188 &logon_divs, /* w */ 1189 &hours_len, /* d */ 1190 &hourslen, &hours, /* B */ 1191 &bad_password_count, /* w */ 1192 &logon_count, /* w */ 1193 &unknown_6); /* d */ 1194 1195 if (len == (uint32) -1) { 1196 ret = False; 1197 goto done; 1198 } 1199 1200 pdb_set_logon_time(sampass, logon_time, PDB_SET); 1201 pdb_set_logoff_time(sampass, logoff_time, PDB_SET); 1202 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); 1203 1204 /* Change from V0 is addition of bad_password_time field. */ 1205 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); 1206 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); 1207 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); 1208 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); 1209 1210 pdb_set_username(sampass, username, PDB_SET); 1211 pdb_set_domain(sampass, domain, PDB_SET); 1212 pdb_set_nt_username(sampass, nt_username, PDB_SET); 1213 pdb_set_fullname(sampass, fullname, PDB_SET); 1214 1215 if (homedir) { 1216 pdb_set_homedir(sampass, homedir, PDB_SET); 1217 } 1218 else { 1219 pdb_set_homedir(sampass, 1220 talloc_sub_basic(sampass, username, domain, 1221 lp_logon_home()), 1222 PDB_DEFAULT); 1223 } 1224 1225 if (dir_drive) 1226 pdb_set_dir_drive(sampass, dir_drive, PDB_SET); 1227 else { 1228 pdb_set_dir_drive(sampass, 1229 talloc_sub_basic(sampass, username, domain, 1230 lp_logon_drive()), 1231 PDB_DEFAULT); 1232 } 1233 1234 if (logon_script) 1235 pdb_set_logon_script(sampass, logon_script, PDB_SET); 1236 else { 1237 pdb_set_logon_script(sampass, 1238 talloc_sub_basic(sampass, username, domain, 1239 lp_logon_script()), 1240 PDB_DEFAULT); 1241 } 1242 1243 if (profile_path) { 1244 pdb_set_profile_path(sampass, profile_path, PDB_SET); 1245 } else { 1246 pdb_set_profile_path(sampass, 1247 talloc_sub_basic(sampass, username, domain, 1248 lp_logon_path()), 1249 PDB_DEFAULT); 1250 } 1251 1252 pdb_set_acct_desc(sampass, acct_desc, PDB_SET); 1253 pdb_set_workstations(sampass, workstations, PDB_SET); 1254 pdb_set_munged_dial(sampass, munged_dial, PDB_SET); 1255 1256 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { 1257 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { 1258 ret = False; 1259 goto done; 1260 } 1261 } 1262 1263 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { 1264 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { 1265 ret = False; 1266 goto done; 1267 } 1268 } 1269 1270 pdb_set_pw_history(sampass, NULL, 0, PDB_SET); 1271 1272 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); 1273 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); 1274 pdb_set_hours_len(sampass, hours_len, PDB_SET); 1275 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); 1276 pdb_set_logon_count(sampass, logon_count, PDB_SET); 1277 pdb_set_unknown_6(sampass, unknown_6, PDB_SET); 1278 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); 1279 pdb_set_logon_divs(sampass, logon_divs, PDB_SET); 1280 pdb_set_hours(sampass, hours, PDB_SET); 1281 1282done: 1283 1284 SAFE_FREE(username); 1285 SAFE_FREE(domain); 1286 SAFE_FREE(nt_username); 1287 SAFE_FREE(fullname); 1288 SAFE_FREE(homedir); 1289 SAFE_FREE(dir_drive); 1290 SAFE_FREE(logon_script); 1291 SAFE_FREE(profile_path); 1292 SAFE_FREE(acct_desc); 1293 SAFE_FREE(workstations); 1294 SAFE_FREE(munged_dial); 1295 SAFE_FREE(unknown_str); 1296 SAFE_FREE(lm_pw_ptr); 1297 SAFE_FREE(nt_pw_ptr); 1298 SAFE_FREE(hours); 1299 1300 return ret; 1301} 1302 1303static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen) 1304{ 1305 1306 /* times are stored as 32bit integer 1307 take care on system with 64bit wide time_t 1308 --SSS */ 1309 uint32 logon_time, 1310 logoff_time, 1311 kickoff_time, 1312 bad_password_time, 1313 pass_last_set_time, 1314 pass_can_change_time, 1315 pass_must_change_time; 1316 char *username = NULL; 1317 char *domain = NULL; 1318 char *nt_username = NULL; 1319 char *dir_drive = NULL; 1320 char *unknown_str = NULL; 1321 char *munged_dial = NULL; 1322 char *fullname = NULL; 1323 char *homedir = NULL; 1324 char *logon_script = NULL; 1325 char *profile_path = NULL; 1326 char *acct_desc = NULL; 1327 char *workstations = NULL; 1328 uint32 username_len, domain_len, nt_username_len, 1329 dir_drive_len, unknown_str_len, munged_dial_len, 1330 fullname_len, homedir_len, logon_script_len, 1331 profile_path_len, acct_desc_len, workstations_len; 1332 1333 uint32 user_rid, group_rid, hours_len, unknown_6; 1334 uint16 acct_ctrl, logon_divs; 1335 uint16 bad_password_count, logon_count; 1336 uint8 *hours = NULL; 1337 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL; 1338 uint32 len = 0; 1339 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen; 1340 uint32 pwHistLen = 0; 1341 bool ret = True; 1342 fstring tmp_string; 1343 bool expand_explicit = lp_passdb_expand_explicit(); 1344 1345 if(sampass == NULL || buf == NULL) { 1346 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n")); 1347 return False; 1348 } 1349 1350/* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */ 1351 1352 /* unpack the buffer into variables */ 1353 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2, 1354 &logon_time, /* d */ 1355 &logoff_time, /* d */ 1356 &kickoff_time, /* d */ 1357 &bad_password_time, /* d */ 1358 &pass_last_set_time, /* d */ 1359 &pass_can_change_time, /* d */ 1360 &pass_must_change_time, /* d */ 1361 &username_len, &username, /* B */ 1362 &domain_len, &domain, /* B */ 1363 &nt_username_len, &nt_username, /* B */ 1364 &fullname_len, &fullname, /* B */ 1365 &homedir_len, &homedir, /* B */ 1366 &dir_drive_len, &dir_drive, /* B */ 1367 &logon_script_len, &logon_script, /* B */ 1368 &profile_path_len, &profile_path, /* B */ 1369 &acct_desc_len, &acct_desc, /* B */ 1370 &workstations_len, &workstations, /* B */ 1371 &unknown_str_len, &unknown_str, /* B */ 1372 &munged_dial_len, &munged_dial, /* B */ 1373 &user_rid, /* d */ 1374 &group_rid, /* d */ 1375 &lm_pw_len, &lm_pw_ptr, /* B */ 1376 &nt_pw_len, &nt_pw_ptr, /* B */ 1377 /* Change from V1 is addition of password history field. */ 1378 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */ 1379 &acct_ctrl, /* w */ 1380 /* Also "remove_me" field was removed. */ 1381 &logon_divs, /* w */ 1382 &hours_len, /* d */ 1383 &hourslen, &hours, /* B */ 1384 &bad_password_count, /* w */ 1385 &logon_count, /* w */ 1386 &unknown_6); /* d */ 1387 1388 if (len == (uint32) -1) { 1389 ret = False; 1390 goto done; 1391 } 1392 1393 pdb_set_logon_time(sampass, logon_time, PDB_SET); 1394 pdb_set_logoff_time(sampass, logoff_time, PDB_SET); 1395 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); 1396 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); 1397 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); 1398 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); 1399 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); 1400 1401 pdb_set_username(sampass, username, PDB_SET); 1402 pdb_set_domain(sampass, domain, PDB_SET); 1403 pdb_set_nt_username(sampass, nt_username, PDB_SET); 1404 pdb_set_fullname(sampass, fullname, PDB_SET); 1405 1406 if (homedir) { 1407 fstrcpy( tmp_string, homedir ); 1408 if (expand_explicit) { 1409 standard_sub_basic( username, domain, tmp_string, 1410 sizeof(tmp_string) ); 1411 } 1412 pdb_set_homedir(sampass, tmp_string, PDB_SET); 1413 } 1414 else { 1415 pdb_set_homedir(sampass, 1416 talloc_sub_basic(sampass, username, domain, 1417 lp_logon_home()), 1418 PDB_DEFAULT); 1419 } 1420 1421 if (dir_drive) 1422 pdb_set_dir_drive(sampass, dir_drive, PDB_SET); 1423 else 1424 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT ); 1425 1426 if (logon_script) { 1427 fstrcpy( tmp_string, logon_script ); 1428 if (expand_explicit) { 1429 standard_sub_basic( username, domain, tmp_string, 1430 sizeof(tmp_string) ); 1431 } 1432 pdb_set_logon_script(sampass, tmp_string, PDB_SET); 1433 } 1434 else { 1435 pdb_set_logon_script(sampass, 1436 talloc_sub_basic(sampass, username, domain, 1437 lp_logon_script()), 1438 PDB_DEFAULT); 1439 } 1440 1441 if (profile_path) { 1442 fstrcpy( tmp_string, profile_path ); 1443 if (expand_explicit) { 1444 standard_sub_basic( username, domain, tmp_string, 1445 sizeof(tmp_string) ); 1446 } 1447 pdb_set_profile_path(sampass, tmp_string, PDB_SET); 1448 } 1449 else { 1450 pdb_set_profile_path(sampass, 1451 talloc_sub_basic(sampass, username, domain, 1452 lp_logon_path()), 1453 PDB_DEFAULT); 1454 } 1455 1456 pdb_set_acct_desc(sampass, acct_desc, PDB_SET); 1457 pdb_set_workstations(sampass, workstations, PDB_SET); 1458 pdb_set_munged_dial(sampass, munged_dial, PDB_SET); 1459 1460 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { 1461 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { 1462 ret = False; 1463 goto done; 1464 } 1465 } 1466 1467 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { 1468 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { 1469 ret = False; 1470 goto done; 1471 } 1472 } 1473 1474 /* Change from V1 is addition of password history field. */ 1475 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); 1476 if (pwHistLen) { 1477 uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN); 1478 if (!pw_hist) { 1479 ret = False; 1480 goto done; 1481 } 1482 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN); 1483 if (nt_pw_hist_ptr && nt_pw_hist_len) { 1484 int i; 1485 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0); 1486 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN; 1487 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) { 1488 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN], 1489 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN], 1490 PW_HISTORY_ENTRY_LEN); 1491 } 1492 } 1493 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) { 1494 SAFE_FREE(pw_hist); 1495 ret = False; 1496 goto done; 1497 } 1498 SAFE_FREE(pw_hist); 1499 } else { 1500 pdb_set_pw_history(sampass, NULL, 0, PDB_SET); 1501 } 1502 1503 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); 1504 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); 1505 pdb_set_hours_len(sampass, hours_len, PDB_SET); 1506 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); 1507 pdb_set_logon_count(sampass, logon_count, PDB_SET); 1508 pdb_set_unknown_6(sampass, unknown_6, PDB_SET); 1509 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); 1510 pdb_set_logon_divs(sampass, logon_divs, PDB_SET); 1511 pdb_set_hours(sampass, hours, PDB_SET); 1512 1513done: 1514 1515 SAFE_FREE(username); 1516 SAFE_FREE(domain); 1517 SAFE_FREE(nt_username); 1518 SAFE_FREE(fullname); 1519 SAFE_FREE(homedir); 1520 SAFE_FREE(dir_drive); 1521 SAFE_FREE(logon_script); 1522 SAFE_FREE(profile_path); 1523 SAFE_FREE(acct_desc); 1524 SAFE_FREE(workstations); 1525 SAFE_FREE(munged_dial); 1526 SAFE_FREE(unknown_str); 1527 SAFE_FREE(lm_pw_ptr); 1528 SAFE_FREE(nt_pw_ptr); 1529 SAFE_FREE(nt_pw_hist_ptr); 1530 SAFE_FREE(hours); 1531 1532 return ret; 1533} 1534 1535/********************************************************************* 1536*********************************************************************/ 1537 1538static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen) 1539{ 1540 1541 /* times are stored as 32bit integer 1542 take care on system with 64bit wide time_t 1543 --SSS */ 1544 uint32 logon_time, 1545 logoff_time, 1546 kickoff_time, 1547 bad_password_time, 1548 pass_last_set_time, 1549 pass_can_change_time, 1550 pass_must_change_time; 1551 char *username = NULL; 1552 char *domain = NULL; 1553 char *nt_username = NULL; 1554 char *dir_drive = NULL; 1555 char *comment = NULL; 1556 char *munged_dial = NULL; 1557 char *fullname = NULL; 1558 char *homedir = NULL; 1559 char *logon_script = NULL; 1560 char *profile_path = NULL; 1561 char *acct_desc = NULL; 1562 char *workstations = NULL; 1563 uint32 username_len, domain_len, nt_username_len, 1564 dir_drive_len, comment_len, munged_dial_len, 1565 fullname_len, homedir_len, logon_script_len, 1566 profile_path_len, acct_desc_len, workstations_len; 1567 1568 uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl; 1569 uint16 logon_divs; 1570 uint16 bad_password_count, logon_count; 1571 uint8 *hours = NULL; 1572 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL; 1573 uint32 len = 0; 1574 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen; 1575 uint32 pwHistLen = 0; 1576 bool ret = True; 1577 fstring tmp_string; 1578 bool expand_explicit = lp_passdb_expand_explicit(); 1579 1580 if(sampass == NULL || buf == NULL) { 1581 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n")); 1582 return False; 1583 } 1584 1585/* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */ 1586 1587 /* unpack the buffer into variables */ 1588 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3, 1589 &logon_time, /* d */ 1590 &logoff_time, /* d */ 1591 &kickoff_time, /* d */ 1592 &bad_password_time, /* d */ 1593 &pass_last_set_time, /* d */ 1594 &pass_can_change_time, /* d */ 1595 &pass_must_change_time, /* d */ 1596 &username_len, &username, /* B */ 1597 &domain_len, &domain, /* B */ 1598 &nt_username_len, &nt_username, /* B */ 1599 &fullname_len, &fullname, /* B */ 1600 &homedir_len, &homedir, /* B */ 1601 &dir_drive_len, &dir_drive, /* B */ 1602 &logon_script_len, &logon_script, /* B */ 1603 &profile_path_len, &profile_path, /* B */ 1604 &acct_desc_len, &acct_desc, /* B */ 1605 &workstations_len, &workstations, /* B */ 1606 &comment_len, &comment, /* B */ 1607 &munged_dial_len, &munged_dial, /* B */ 1608 &user_rid, /* d */ 1609 &group_rid, /* d */ 1610 &lm_pw_len, &lm_pw_ptr, /* B */ 1611 &nt_pw_len, &nt_pw_ptr, /* B */ 1612 /* Change from V1 is addition of password history field. */ 1613 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */ 1614 /* Change from V2 is the uint32 acb_mask */ 1615 &acct_ctrl, /* d */ 1616 /* Also "remove_me" field was removed. */ 1617 &logon_divs, /* w */ 1618 &hours_len, /* d */ 1619 &hourslen, &hours, /* B */ 1620 &bad_password_count, /* w */ 1621 &logon_count, /* w */ 1622 &unknown_6); /* d */ 1623 1624 if (len == (uint32) -1) { 1625 ret = False; 1626 goto done; 1627 } 1628 1629 pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET); 1630 pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET); 1631 pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET); 1632 pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET); 1633 pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET); 1634 pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET); 1635 pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET); 1636 1637 pdb_set_username(sampass, username, PDB_SET); 1638 pdb_set_domain(sampass, domain, PDB_SET); 1639 pdb_set_nt_username(sampass, nt_username, PDB_SET); 1640 pdb_set_fullname(sampass, fullname, PDB_SET); 1641 1642 if (homedir) { 1643 fstrcpy( tmp_string, homedir ); 1644 if (expand_explicit) { 1645 standard_sub_basic( username, domain, tmp_string, 1646 sizeof(tmp_string) ); 1647 } 1648 pdb_set_homedir(sampass, tmp_string, PDB_SET); 1649 } 1650 else { 1651 pdb_set_homedir(sampass, 1652 talloc_sub_basic(sampass, username, domain, 1653 lp_logon_home()), 1654 PDB_DEFAULT); 1655 } 1656 1657 if (dir_drive) 1658 pdb_set_dir_drive(sampass, dir_drive, PDB_SET); 1659 else 1660 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT ); 1661 1662 if (logon_script) { 1663 fstrcpy( tmp_string, logon_script ); 1664 if (expand_explicit) { 1665 standard_sub_basic( username, domain, tmp_string, 1666 sizeof(tmp_string) ); 1667 } 1668 pdb_set_logon_script(sampass, tmp_string, PDB_SET); 1669 } 1670 else { 1671 pdb_set_logon_script(sampass, 1672 talloc_sub_basic(sampass, username, domain, 1673 lp_logon_script()), 1674 PDB_DEFAULT); 1675 } 1676 1677 if (profile_path) { 1678 fstrcpy( tmp_string, profile_path ); 1679 if (expand_explicit) { 1680 standard_sub_basic( username, domain, tmp_string, 1681 sizeof(tmp_string) ); 1682 } 1683 pdb_set_profile_path(sampass, tmp_string, PDB_SET); 1684 } 1685 else { 1686 pdb_set_profile_path(sampass, 1687 talloc_sub_basic(sampass, username, domain, lp_logon_path()), 1688 PDB_DEFAULT); 1689 } 1690 1691 pdb_set_acct_desc(sampass, acct_desc, PDB_SET); 1692 pdb_set_comment(sampass, comment, PDB_SET); 1693 pdb_set_workstations(sampass, workstations, PDB_SET); 1694 pdb_set_munged_dial(sampass, munged_dial, PDB_SET); 1695 1696 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { 1697 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { 1698 ret = False; 1699 goto done; 1700 } 1701 } 1702 1703 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { 1704 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { 1705 ret = False; 1706 goto done; 1707 } 1708 } 1709 1710 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); 1711 if (pwHistLen) { 1712 uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN); 1713 if (!pw_hist) { 1714 ret = False; 1715 goto done; 1716 } 1717 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN); 1718 if (nt_pw_hist_ptr && nt_pw_hist_len) { 1719 int i; 1720 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0); 1721 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN; 1722 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) { 1723 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN], 1724 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN], 1725 PW_HISTORY_ENTRY_LEN); 1726 } 1727 } 1728 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) { 1729 SAFE_FREE(pw_hist); 1730 ret = False; 1731 goto done; 1732 } 1733 SAFE_FREE(pw_hist); 1734 } else { 1735 pdb_set_pw_history(sampass, NULL, 0, PDB_SET); 1736 } 1737 1738 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); 1739 pdb_set_hours_len(sampass, hours_len, PDB_SET); 1740 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); 1741 pdb_set_logon_count(sampass, logon_count, PDB_SET); 1742 pdb_set_unknown_6(sampass, unknown_6, PDB_SET); 1743 /* Change from V2 is the uint32 acct_ctrl */ 1744 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); 1745 pdb_set_logon_divs(sampass, logon_divs, PDB_SET); 1746 pdb_set_hours(sampass, hours, PDB_SET); 1747 1748done: 1749 1750 SAFE_FREE(username); 1751 SAFE_FREE(domain); 1752 SAFE_FREE(nt_username); 1753 SAFE_FREE(fullname); 1754 SAFE_FREE(homedir); 1755 SAFE_FREE(dir_drive); 1756 SAFE_FREE(logon_script); 1757 SAFE_FREE(profile_path); 1758 SAFE_FREE(acct_desc); 1759 SAFE_FREE(workstations); 1760 SAFE_FREE(munged_dial); 1761 SAFE_FREE(comment); 1762 SAFE_FREE(lm_pw_ptr); 1763 SAFE_FREE(nt_pw_ptr); 1764 SAFE_FREE(nt_pw_hist_ptr); 1765 SAFE_FREE(hours); 1766 1767 return ret; 1768} 1769 1770/********************************************************************* 1771*********************************************************************/ 1772 1773static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool size_only) 1774{ 1775 size_t len, buflen; 1776 1777 /* times are stored as 32bit integer 1778 take care on system with 64bit wide time_t 1779 --SSS */ 1780 uint32 logon_time, 1781 logoff_time, 1782 kickoff_time, 1783 bad_password_time, 1784 pass_last_set_time, 1785 pass_can_change_time, 1786 pass_must_change_time; 1787 1788 uint32 user_rid, group_rid; 1789 1790 const char *username; 1791 const char *domain; 1792 const char *nt_username; 1793 const char *dir_drive; 1794 const char *comment; 1795 const char *munged_dial; 1796 const char *fullname; 1797 const char *homedir; 1798 const char *logon_script; 1799 const char *profile_path; 1800 const char *acct_desc; 1801 const char *workstations; 1802 uint32 username_len, domain_len, nt_username_len, 1803 dir_drive_len, comment_len, munged_dial_len, 1804 fullname_len, homedir_len, logon_script_len, 1805 profile_path_len, acct_desc_len, workstations_len; 1806 1807 const uint8 *lm_pw; 1808 const uint8 *nt_pw; 1809 const uint8 *nt_pw_hist; 1810 uint32 lm_pw_len = 16; 1811 uint32 nt_pw_len = 16; 1812 uint32 nt_pw_hist_len; 1813 uint32 pwHistLen = 0; 1814 1815 *buf = NULL; 1816 buflen = 0; 1817 1818 logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass)); 1819 logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass)); 1820 kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass)); 1821 bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass)); 1822 pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass)); 1823 pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass)); 1824 pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass)); 1825 1826 user_rid = pdb_get_user_rid(sampass); 1827 group_rid = pdb_get_group_rid(sampass); 1828 1829 username = pdb_get_username(sampass); 1830 if (username) { 1831 username_len = strlen(username) +1; 1832 } else { 1833 username_len = 0; 1834 } 1835 1836 domain = pdb_get_domain(sampass); 1837 if (domain) { 1838 domain_len = strlen(domain) +1; 1839 } else { 1840 domain_len = 0; 1841 } 1842 1843 nt_username = pdb_get_nt_username(sampass); 1844 if (nt_username) { 1845 nt_username_len = strlen(nt_username) +1; 1846 } else { 1847 nt_username_len = 0; 1848 } 1849 1850 fullname = pdb_get_fullname(sampass); 1851 if (fullname) { 1852 fullname_len = strlen(fullname) +1; 1853 } else { 1854 fullname_len = 0; 1855 } 1856 1857 /* 1858 * Only updates fields which have been set (not defaults from smb.conf) 1859 */ 1860 1861 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) { 1862 dir_drive = pdb_get_dir_drive(sampass); 1863 } else { 1864 dir_drive = NULL; 1865 } 1866 if (dir_drive) { 1867 dir_drive_len = strlen(dir_drive) +1; 1868 } else { 1869 dir_drive_len = 0; 1870 } 1871 1872 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) { 1873 homedir = pdb_get_homedir(sampass); 1874 } else { 1875 homedir = NULL; 1876 } 1877 if (homedir) { 1878 homedir_len = strlen(homedir) +1; 1879 } else { 1880 homedir_len = 0; 1881 } 1882 1883 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) { 1884 logon_script = pdb_get_logon_script(sampass); 1885 } else { 1886 logon_script = NULL; 1887 } 1888 if (logon_script) { 1889 logon_script_len = strlen(logon_script) +1; 1890 } else { 1891 logon_script_len = 0; 1892 } 1893 1894 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) { 1895 profile_path = pdb_get_profile_path(sampass); 1896 } else { 1897 profile_path = NULL; 1898 } 1899 if (profile_path) { 1900 profile_path_len = strlen(profile_path) +1; 1901 } else { 1902 profile_path_len = 0; 1903 } 1904 1905 lm_pw = pdb_get_lanman_passwd(sampass); 1906 if (!lm_pw) { 1907 lm_pw_len = 0; 1908 } 1909 1910 nt_pw = pdb_get_nt_passwd(sampass); 1911 if (!nt_pw) { 1912 nt_pw_len = 0; 1913 } 1914 1915 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); 1916 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len); 1917 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) { 1918 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN; 1919 } else { 1920 nt_pw_hist_len = 0; 1921 } 1922 1923 acct_desc = pdb_get_acct_desc(sampass); 1924 if (acct_desc) { 1925 acct_desc_len = strlen(acct_desc) +1; 1926 } else { 1927 acct_desc_len = 0; 1928 } 1929 1930 workstations = pdb_get_workstations(sampass); 1931 if (workstations) { 1932 workstations_len = strlen(workstations) +1; 1933 } else { 1934 workstations_len = 0; 1935 } 1936 1937 comment = pdb_get_comment(sampass); 1938 if (comment) { 1939 comment_len = strlen(comment) +1; 1940 } else { 1941 comment_len = 0; 1942 } 1943 1944 munged_dial = pdb_get_munged_dial(sampass); 1945 if (munged_dial) { 1946 munged_dial_len = strlen(munged_dial) +1; 1947 } else { 1948 munged_dial_len = 0; 1949 } 1950 1951/* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */ 1952 1953 /* one time to get the size needed */ 1954 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3, 1955 logon_time, /* d */ 1956 logoff_time, /* d */ 1957 kickoff_time, /* d */ 1958 bad_password_time, /* d */ 1959 pass_last_set_time, /* d */ 1960 pass_can_change_time, /* d */ 1961 pass_must_change_time, /* d */ 1962 username_len, username, /* B */ 1963 domain_len, domain, /* B */ 1964 nt_username_len, nt_username, /* B */ 1965 fullname_len, fullname, /* B */ 1966 homedir_len, homedir, /* B */ 1967 dir_drive_len, dir_drive, /* B */ 1968 logon_script_len, logon_script, /* B */ 1969 profile_path_len, profile_path, /* B */ 1970 acct_desc_len, acct_desc, /* B */ 1971 workstations_len, workstations, /* B */ 1972 comment_len, comment, /* B */ 1973 munged_dial_len, munged_dial, /* B */ 1974 user_rid, /* d */ 1975 group_rid, /* d */ 1976 lm_pw_len, lm_pw, /* B */ 1977 nt_pw_len, nt_pw, /* B */ 1978 nt_pw_hist_len, nt_pw_hist, /* B */ 1979 pdb_get_acct_ctrl(sampass), /* d */ 1980 pdb_get_logon_divs(sampass), /* w */ 1981 pdb_get_hours_len(sampass), /* d */ 1982 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */ 1983 pdb_get_bad_password_count(sampass), /* w */ 1984 pdb_get_logon_count(sampass), /* w */ 1985 pdb_get_unknown_6(sampass)); /* d */ 1986 1987 if (size_only) { 1988 return buflen; 1989 } 1990 1991 /* malloc the space needed */ 1992 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) { 1993 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n")); 1994 return (-1); 1995 } 1996 1997 /* now for the real call to tdb_pack() */ 1998 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3, 1999 logon_time, /* d */ 2000 logoff_time, /* d */ 2001 kickoff_time, /* d */ 2002 bad_password_time, /* d */ 2003 pass_last_set_time, /* d */ 2004 pass_can_change_time, /* d */ 2005 pass_must_change_time, /* d */ 2006 username_len, username, /* B */ 2007 domain_len, domain, /* B */ 2008 nt_username_len, nt_username, /* B */ 2009 fullname_len, fullname, /* B */ 2010 homedir_len, homedir, /* B */ 2011 dir_drive_len, dir_drive, /* B */ 2012 logon_script_len, logon_script, /* B */ 2013 profile_path_len, profile_path, /* B */ 2014 acct_desc_len, acct_desc, /* B */ 2015 workstations_len, workstations, /* B */ 2016 comment_len, comment, /* B */ 2017 munged_dial_len, munged_dial, /* B */ 2018 user_rid, /* d */ 2019 group_rid, /* d */ 2020 lm_pw_len, lm_pw, /* B */ 2021 nt_pw_len, nt_pw, /* B */ 2022 nt_pw_hist_len, nt_pw_hist, /* B */ 2023 pdb_get_acct_ctrl(sampass), /* d */ 2024 pdb_get_logon_divs(sampass), /* w */ 2025 pdb_get_hours_len(sampass), /* d */ 2026 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */ 2027 pdb_get_bad_password_count(sampass), /* w */ 2028 pdb_get_logon_count(sampass), /* w */ 2029 pdb_get_unknown_6(sampass)); /* d */ 2030 2031 /* check to make sure we got it correct */ 2032 if (buflen != len) { 2033 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", 2034 (unsigned long)buflen, (unsigned long)len)); 2035 /* error */ 2036 SAFE_FREE (*buf); 2037 return (-1); 2038 } 2039 2040 return (buflen); 2041} 2042 2043static bool init_samu_from_buffer_v4(struct samu *sampass, uint8 *buf, uint32 buflen) 2044{ 2045 /* nothing changed between V3 and V4 */ 2046 return init_samu_from_buffer_v3(sampass, buf, buflen); 2047} 2048 2049static uint32 init_buffer_from_samu_v4(uint8 **buf, struct samu *sampass, bool size_only) 2050{ 2051 /* nothing changed between V3 and V4 */ 2052 return init_buffer_from_samu_v3(buf, sampass, size_only); 2053} 2054 2055/********************************************************************** 2056 Intialize a struct samu struct from a BYTE buffer of size len 2057 *********************************************************************/ 2058 2059bool init_samu_from_buffer(struct samu *sampass, uint32_t level, 2060 uint8 *buf, uint32 buflen) 2061{ 2062 switch (level) { 2063 case SAMU_BUFFER_V0: 2064 return init_samu_from_buffer_v0(sampass, buf, buflen); 2065 case SAMU_BUFFER_V1: 2066 return init_samu_from_buffer_v1(sampass, buf, buflen); 2067 case SAMU_BUFFER_V2: 2068 return init_samu_from_buffer_v2(sampass, buf, buflen); 2069 case SAMU_BUFFER_V3: 2070 return init_samu_from_buffer_v3(sampass, buf, buflen); 2071 case SAMU_BUFFER_V4: 2072 return init_samu_from_buffer_v4(sampass, buf, buflen); 2073 } 2074 2075 return false; 2076} 2077 2078/********************************************************************** 2079 Intialize a BYTE buffer from a struct samu struct 2080 *********************************************************************/ 2081 2082uint32 init_buffer_from_samu (uint8 **buf, struct samu *sampass, bool size_only) 2083{ 2084 return init_buffer_from_samu_v4(buf, sampass, size_only); 2085} 2086 2087/********************************************************************* 2088*********************************************************************/ 2089 2090bool pdb_copy_sam_account(struct samu *dst, struct samu *src ) 2091{ 2092 uint8 *buf = NULL; 2093 int len; 2094 2095 len = init_buffer_from_samu(&buf, src, False); 2096 if (len == -1 || !buf) { 2097 SAFE_FREE(buf); 2098 return False; 2099 } 2100 2101 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) { 2102 free(buf); 2103 return False; 2104 } 2105 2106 dst->methods = src->methods; 2107 2108 if ( src->unix_pw ) { 2109 dst->unix_pw = tcopy_passwd( dst, src->unix_pw ); 2110 if (!dst->unix_pw) { 2111 free(buf); 2112 return False; 2113 } 2114 } 2115 2116 if (src->group_sid) { 2117 pdb_set_group_sid(dst, src->group_sid, PDB_SET); 2118 } 2119 2120 free(buf); 2121 return True; 2122} 2123 2124/********************************************************************* 2125 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME 2126*********************************************************************/ 2127 2128bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) 2129{ 2130 time_t LastBadPassword; 2131 uint16 BadPasswordCount; 2132 uint32 resettime; 2133 bool res; 2134 2135 BadPasswordCount = pdb_get_bad_password_count(sampass); 2136 if (!BadPasswordCount) { 2137 DEBUG(9, ("No bad password attempts.\n")); 2138 return True; 2139 } 2140 2141 become_root(); 2142 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime); 2143 unbecome_root(); 2144 2145 if (!res) { 2146 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n")); 2147 return False; 2148 } 2149 2150 /* First, check if there is a reset time to compare */ 2151 if ((resettime == (uint32) -1) || (resettime == 0)) { 2152 DEBUG(9, ("No reset time, can't reset bad pw count\n")); 2153 return True; 2154 } 2155 2156 LastBadPassword = pdb_get_bad_password_time(sampass); 2157 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n", 2158 (uint32) LastBadPassword, resettime, (uint32)time(NULL))); 2159 if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){ 2160 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); 2161 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); 2162 if (updated) { 2163 *updated = True; 2164 } 2165 } 2166 2167 return True; 2168} 2169 2170/********************************************************************* 2171 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION 2172*********************************************************************/ 2173 2174bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) 2175{ 2176 uint32 duration; 2177 time_t LastBadPassword; 2178 bool res; 2179 2180 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) { 2181 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n", 2182 pdb_get_username(sampass))); 2183 return True; 2184 } 2185 2186 become_root(); 2187 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration); 2188 unbecome_root(); 2189 2190 if (!res) { 2191 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n")); 2192 return False; 2193 } 2194 2195 /* First, check if there is a duration to compare */ 2196 if ((duration == (uint32) -1) || (duration == 0)) { 2197 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n")); 2198 return True; 2199 } 2200 2201 LastBadPassword = pdb_get_bad_password_time(sampass); 2202 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n", 2203 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL))); 2204 2205 if (LastBadPassword == (time_t)0) { 2206 DEBUG(1,("pdb_update_autolock_flag: Account %s " 2207 "administratively locked out with no bad password " 2208 "time. Leaving locked out.\n", 2209 pdb_get_username(sampass) )); 2210 return True; 2211 } 2212 2213 if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) { 2214 pdb_set_acct_ctrl(sampass, 2215 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK, 2216 PDB_CHANGED); 2217 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); 2218 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); 2219 if (updated) { 2220 *updated = True; 2221 } 2222 } 2223 2224 return True; 2225} 2226 2227/********************************************************************* 2228 Increment the bad_password_count 2229*********************************************************************/ 2230 2231bool pdb_increment_bad_password_count(struct samu *sampass) 2232{ 2233 uint32 account_policy_lockout; 2234 bool autolock_updated = False, badpw_updated = False; 2235 bool ret; 2236 2237 /* Retrieve the account lockout policy */ 2238 become_root(); 2239 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); 2240 unbecome_root(); 2241 if ( !ret ) { 2242 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n")); 2243 return False; 2244 } 2245 2246 /* If there is no policy, we don't need to continue checking */ 2247 if (!account_policy_lockout) { 2248 DEBUG(9, ("No lockout policy, don't track bad passwords\n")); 2249 return True; 2250 } 2251 2252 /* Check if the autolock needs to be cleared */ 2253 if (!pdb_update_autolock_flag(sampass, &autolock_updated)) 2254 return False; 2255 2256 /* Check if the badpw count needs to be reset */ 2257 if (!pdb_update_bad_password_count(sampass, &badpw_updated)) 2258 return False; 2259 2260 /* 2261 Ok, now we can assume that any resetting that needs to be 2262 done has been done, and just get on with incrementing 2263 and autolocking if necessary 2264 */ 2265 2266 pdb_set_bad_password_count(sampass, 2267 pdb_get_bad_password_count(sampass)+1, 2268 PDB_CHANGED); 2269 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED); 2270 2271 2272 if (pdb_get_bad_password_count(sampass) < account_policy_lockout) 2273 return True; 2274 2275 if (!pdb_set_acct_ctrl(sampass, 2276 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK, 2277 PDB_CHANGED)) { 2278 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); 2279 return False; 2280 } 2281 2282 return True; 2283} 2284 2285bool is_dc_trusted_domain_situation(const char *domain_name) 2286{ 2287 return IS_DC && !strequal(domain_name, lp_workgroup()); 2288} 2289 2290/******************************************************************* 2291 Wrapper around retrieving the clear text trust account password. 2292 appropriate account name is stored in account_name. 2293 Caller must free password, but not account_name. 2294*******************************************************************/ 2295 2296bool get_trust_pw_clear(const char *domain, char **ret_pwd, 2297 const char **account_name, 2298 enum netr_SchannelType *channel) 2299{ 2300 char *pwd; 2301 time_t last_set_time; 2302 2303 /* if we are a DC and this is not our domain, then lookup an account 2304 * for the domain trust */ 2305 2306 if (is_dc_trusted_domain_situation(domain)) { 2307 if (!lp_allow_trusted_domains()) { 2308 return false; 2309 } 2310 2311 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL, 2312 &last_set_time)) 2313 { 2314 DEBUG(0, ("get_trust_pw: could not fetch trust " 2315 "account password for trusted domain %s\n", 2316 domain)); 2317 return false; 2318 } 2319 2320 if (channel != NULL) { 2321 *channel = SEC_CHAN_DOMAIN; 2322 } 2323 2324 if (account_name != NULL) { 2325 *account_name = lp_workgroup(); 2326 } 2327 2328 return true; 2329 } 2330 2331 /* 2332 * Since we can only be member of one single domain, we are now 2333 * in a member situation: 2334 * 2335 * - Either we are a DC (selfjoined) and the domain is our 2336 * own domain. 2337 * - Or we are on a member and the domain is our own or some 2338 * other (potentially trusted) domain. 2339 * 2340 * In both cases, we can only get the machine account password 2341 * for our own domain to connect to our own dc. (For a member, 2342 * request to trusted domains are performed through our dc.) 2343 * 2344 * So we simply use our own domain name to retrieve the 2345 * machine account passowrd and ignore the request domain here. 2346 */ 2347 2348 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel); 2349 2350 if (pwd != NULL) { 2351 *ret_pwd = pwd; 2352 if (account_name != NULL) { 2353 *account_name = global_myname(); 2354 } 2355 2356 return true; 2357 } 2358 2359 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust " 2360 "account password for domain %s\n", domain)); 2361 return false; 2362} 2363 2364/******************************************************************* 2365 Wrapper around retrieving the trust account password. 2366 appropriate account name is stored in account_name. 2367*******************************************************************/ 2368 2369bool get_trust_pw_hash(const char *domain, uint8 ret_pwd[16], 2370 const char **account_name, 2371 enum netr_SchannelType *channel) 2372{ 2373 char *pwd = NULL; 2374 time_t last_set_time; 2375 2376 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) { 2377 E_md4hash(pwd, ret_pwd); 2378 SAFE_FREE(pwd); 2379 return true; 2380 } else if (is_dc_trusted_domain_situation(domain)) { 2381 return false; 2382 } 2383 2384 /* as a fallback, try to get the hashed pwd directly from the tdb... */ 2385 2386 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd, 2387 &last_set_time, 2388 channel)) 2389 { 2390 if (account_name != NULL) { 2391 *account_name = global_myname(); 2392 } 2393 2394 return true; 2395 } 2396 2397 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account " 2398 "password for domain %s\n", domain)); 2399 return False; 2400} 2401 2402struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx, 2403 struct samu *pw) 2404{ 2405 struct samr_LogonHours hours; 2406 const int units_per_week = 168; 2407 2408 ZERO_STRUCT(hours); 2409 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week); 2410 if (!hours.bits) { 2411 return hours; 2412 } 2413 2414 hours.units_per_week = units_per_week; 2415 memset(hours.bits, 0xFF, units_per_week); 2416 2417 if (pdb_get_hours(pw)) { 2418 memcpy(hours.bits, pdb_get_hours(pw), 2419 MIN(pdb_get_hours_len(pw), units_per_week)); 2420 } 2421 2422 return hours; 2423} 2424