1/* 2 Unix SMB/CIFS implementation. 3 SAMR Pipe utility functions. 4 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 Copyright (C) Guenther Deschner 2008 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 27#undef DBGC_CLASS 28#define DBGC_CLASS DBGC_RPC_SRV 29 30#define STRING_CHANGED (old_string && !new_string) ||\ 31 (!old_string && new_string) ||\ 32 (old_string && new_string && (strcmp(old_string, new_string) != 0)) 33 34#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\ 35 (!(s1) && (s2)) ||\ 36 ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) 37 38/************************************************************* 39 Copies a struct samr_UserInfo2 to a struct samu 40**************************************************************/ 41 42void copy_id2_to_sam_passwd(struct samu *to, 43 struct samr_UserInfo2 *from) 44{ 45 struct samr_UserInfo21 i; 46 47 if (from == NULL || to == NULL) { 48 return; 49 } 50 51 ZERO_STRUCT(i); 52 53 i.fields_present = SAMR_FIELD_COMMENT | 54 SAMR_FIELD_COUNTRY_CODE | 55 SAMR_FIELD_CODE_PAGE; 56 i.comment = from->comment; 57 i.country_code = from->country_code; 58 i.code_page = from->code_page; 59 60 copy_id21_to_sam_passwd("INFO_2", to, &i); 61} 62 63/************************************************************* 64 Copies a struct samr_UserInfo4 to a struct samu 65**************************************************************/ 66 67void copy_id4_to_sam_passwd(struct samu *to, 68 struct samr_UserInfo4 *from) 69{ 70 struct samr_UserInfo21 i; 71 72 if (from == NULL || to == NULL) { 73 return; 74 } 75 76 ZERO_STRUCT(i); 77 78 i.fields_present = SAMR_FIELD_LOGON_HOURS; 79 i.logon_hours = from->logon_hours; 80 81 copy_id21_to_sam_passwd("INFO_4", to, &i); 82} 83 84/************************************************************* 85 Copies a struct samr_UserInfo6 to a struct samu 86**************************************************************/ 87 88void copy_id6_to_sam_passwd(struct samu *to, 89 struct samr_UserInfo6 *from) 90{ 91 struct samr_UserInfo21 i; 92 93 if (from == NULL || to == NULL) { 94 return; 95 } 96 97 ZERO_STRUCT(i); 98 99 i.fields_present = SAMR_FIELD_ACCOUNT_NAME | 100 SAMR_FIELD_FULL_NAME; 101 i.account_name = from->account_name; 102 i.full_name = from->full_name; 103 104 copy_id21_to_sam_passwd("INFO_6", to, &i); 105} 106 107/************************************************************* 108 Copies a struct samr_UserInfo8 to a struct samu 109**************************************************************/ 110 111void copy_id8_to_sam_passwd(struct samu *to, 112 struct samr_UserInfo8 *from) 113{ 114 struct samr_UserInfo21 i; 115 116 if (from == NULL || to == NULL) { 117 return; 118 } 119 120 ZERO_STRUCT(i); 121 122 i.fields_present = SAMR_FIELD_FULL_NAME; 123 i.full_name = from->full_name; 124 125 copy_id21_to_sam_passwd("INFO_8", to, &i); 126} 127 128/************************************************************* 129 Copies a struct samr_UserInfo10 to a struct samu 130**************************************************************/ 131 132void copy_id10_to_sam_passwd(struct samu *to, 133 struct samr_UserInfo10 *from) 134{ 135 struct samr_UserInfo21 i; 136 137 if (from == NULL || to == NULL) { 138 return; 139 } 140 141 ZERO_STRUCT(i); 142 143 i.fields_present = SAMR_FIELD_HOME_DIRECTORY | 144 SAMR_FIELD_HOME_DRIVE; 145 i.home_directory = from->home_directory; 146 i.home_drive = from->home_drive; 147 148 copy_id21_to_sam_passwd("INFO_10", to, &i); 149} 150 151/************************************************************* 152 Copies a struct samr_UserInfo11 to a struct samu 153**************************************************************/ 154 155void copy_id11_to_sam_passwd(struct samu *to, 156 struct samr_UserInfo11 *from) 157{ 158 struct samr_UserInfo21 i; 159 160 if (from == NULL || to == NULL) { 161 return; 162 } 163 164 ZERO_STRUCT(i); 165 166 i.fields_present = SAMR_FIELD_LOGON_SCRIPT; 167 i.logon_script = from->logon_script; 168 169 copy_id21_to_sam_passwd("INFO_11", to, &i); 170} 171 172/************************************************************* 173 Copies a struct samr_UserInfo12 to a struct samu 174**************************************************************/ 175 176void copy_id12_to_sam_passwd(struct samu *to, 177 struct samr_UserInfo12 *from) 178{ 179 struct samr_UserInfo21 i; 180 181 if (from == NULL || to == NULL) { 182 return; 183 } 184 185 ZERO_STRUCT(i); 186 187 i.fields_present = SAMR_FIELD_PROFILE_PATH; 188 i.profile_path = from->profile_path; 189 190 copy_id21_to_sam_passwd("INFO_12", to, &i); 191} 192 193/************************************************************* 194 Copies a struct samr_UserInfo13 to a struct samu 195**************************************************************/ 196 197void copy_id13_to_sam_passwd(struct samu *to, 198 struct samr_UserInfo13 *from) 199{ 200 struct samr_UserInfo21 i; 201 202 if (from == NULL || to == NULL) { 203 return; 204 } 205 206 ZERO_STRUCT(i); 207 208 i.fields_present = SAMR_FIELD_DESCRIPTION; 209 i.description = from->description; 210 211 copy_id21_to_sam_passwd("INFO_13", to, &i); 212} 213 214/************************************************************* 215 Copies a struct samr_UserInfo14 to a struct samu 216**************************************************************/ 217 218void copy_id14_to_sam_passwd(struct samu *to, 219 struct samr_UserInfo14 *from) 220{ 221 struct samr_UserInfo21 i; 222 223 if (from == NULL || to == NULL) { 224 return; 225 } 226 227 ZERO_STRUCT(i); 228 229 i.fields_present = SAMR_FIELD_WORKSTATIONS; 230 i.workstations = from->workstations; 231 232 copy_id21_to_sam_passwd("INFO_14", to, &i); 233} 234 235/************************************************************* 236 Copies a struct samr_UserInfo16 to a struct samu 237**************************************************************/ 238 239void copy_id16_to_sam_passwd(struct samu *to, 240 struct samr_UserInfo16 *from) 241{ 242 struct samr_UserInfo21 i; 243 244 if (from == NULL || to == NULL) { 245 return; 246 } 247 248 ZERO_STRUCT(i); 249 250 i.fields_present = SAMR_FIELD_ACCT_FLAGS; 251 i.acct_flags = from->acct_flags; 252 253 copy_id21_to_sam_passwd("INFO_16", to, &i); 254} 255 256/************************************************************* 257 Copies a struct samr_UserInfo17 to a struct samu 258**************************************************************/ 259 260void copy_id17_to_sam_passwd(struct samu *to, 261 struct samr_UserInfo17 *from) 262{ 263 struct samr_UserInfo21 i; 264 265 if (from == NULL || to == NULL) { 266 return; 267 } 268 269 ZERO_STRUCT(i); 270 271 i.fields_present = SAMR_FIELD_ACCT_EXPIRY; 272 i.acct_expiry = from->acct_expiry; 273 274 copy_id21_to_sam_passwd("INFO_17", to, &i); 275} 276 277/************************************************************* 278 Copies a struct samr_UserInfo18 to a struct samu 279**************************************************************/ 280 281void copy_id18_to_sam_passwd(struct samu *to, 282 struct samr_UserInfo18 *from) 283{ 284 struct samr_UserInfo21 i; 285 286 if (from == NULL || to == NULL) { 287 return; 288 } 289 290 ZERO_STRUCT(i); 291 292 i.fields_present = SAMR_FIELD_EXPIRED_FLAG; 293 i.password_expired = from->password_expired; 294 295 copy_id21_to_sam_passwd("INFO_18", to, &i); 296} 297 298/************************************************************* 299 Copies a struct samr_UserInfo20 to a struct samu 300**************************************************************/ 301 302void copy_id20_to_sam_passwd(struct samu *to, 303 struct samr_UserInfo20 *from) 304{ 305 const char *old_string; 306 char *new_string; 307 DATA_BLOB mung; 308 309 if (from == NULL || to == NULL) { 310 return; 311 } 312 313 if (from->parameters.array) { 314 old_string = pdb_get_munged_dial(to); 315 mung = data_blob_const(from->parameters.array, 316 from->parameters.length); 317 new_string = (mung.length == 0) ? 318 NULL : base64_encode_data_blob(talloc_tos(), mung); 319 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n", 320 old_string, new_string)); 321 if (STRING_CHANGED_NC(old_string,new_string)) { 322 pdb_set_munged_dial(to, new_string, PDB_CHANGED); 323 } 324 325 TALLOC_FREE(new_string); 326 } 327} 328 329/************************************************************* 330 Copies a struct samr_UserInfo21 to a struct samu 331**************************************************************/ 332 333void copy_id21_to_sam_passwd(const char *log_prefix, 334 struct samu *to, 335 struct samr_UserInfo21 *from) 336{ 337 time_t unix_time, stored_time; 338 const char *old_string, *new_string; 339 const char *l; 340 341 if (from == NULL || to == NULL) { 342 return; 343 } 344 345 if (log_prefix) { 346 l = log_prefix; 347 } else { 348 l = "INFO_21"; 349 } 350 351 if (from->fields_present & SAMR_FIELD_LAST_LOGON) { 352 unix_time = nt_time_to_unix(from->last_logon); 353 stored_time = pdb_get_logon_time(to); 354 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l, 355 (long unsigned int)stored_time, 356 (long unsigned int)unix_time)); 357 if (stored_time != unix_time) { 358 pdb_set_logon_time(to, unix_time, PDB_CHANGED); 359 } 360 } 361 362 if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) { 363 unix_time = nt_time_to_unix(from->last_logoff); 364 stored_time = pdb_get_logoff_time(to); 365 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l, 366 (long unsigned int)stored_time, 367 (long unsigned int)unix_time)); 368 if (stored_time != unix_time) { 369 pdb_set_logoff_time(to, unix_time, PDB_CHANGED); 370 } 371 } 372 373 if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) { 374 unix_time = nt_time_to_unix(from->acct_expiry); 375 stored_time = pdb_get_kickoff_time(to); 376 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l, 377 (long unsigned int)stored_time, 378 (long unsigned int)unix_time)); 379 if (stored_time != unix_time) { 380 pdb_set_kickoff_time(to, unix_time , PDB_CHANGED); 381 } 382 } 383 384 if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) { 385 unix_time = nt_time_to_unix(from->last_password_change); 386 stored_time = pdb_get_pass_last_set_time(to); 387 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l, 388 (long unsigned int)stored_time, 389 (long unsigned int)unix_time)); 390 if (stored_time != unix_time) { 391 pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED); 392 } 393 } 394 395 if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) && 396 (from->account_name.string)) { 397 old_string = pdb_get_username(to); 398 new_string = from->account_name.string; 399 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l, 400 old_string, new_string)); 401 if (STRING_CHANGED) { 402 pdb_set_username(to, new_string, PDB_CHANGED); 403 } 404 } 405 406 if ((from->fields_present & SAMR_FIELD_FULL_NAME) && 407 (from->full_name.string)) { 408 old_string = pdb_get_fullname(to); 409 new_string = from->full_name.string; 410 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l, 411 old_string, new_string)); 412 if (STRING_CHANGED) { 413 pdb_set_fullname(to, new_string, PDB_CHANGED); 414 } 415 } 416 417 if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) && 418 (from->home_directory.string)) { 419 old_string = pdb_get_homedir(to); 420 new_string = from->home_directory.string; 421 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l, 422 old_string, new_string)); 423 if (STRING_CHANGED) { 424 pdb_set_homedir(to, new_string, PDB_CHANGED); 425 } 426 } 427 428 if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) && 429 (from->home_drive.string)) { 430 old_string = pdb_get_dir_drive(to); 431 new_string = from->home_drive.string; 432 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l, 433 old_string, new_string)); 434 if (STRING_CHANGED) { 435 pdb_set_dir_drive(to, new_string, PDB_CHANGED); 436 } 437 } 438 439 if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) && 440 (from->logon_script.string)) { 441 old_string = pdb_get_logon_script(to); 442 new_string = from->logon_script.string; 443 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l, 444 old_string, new_string)); 445 if (STRING_CHANGED) { 446 pdb_set_logon_script(to , new_string, PDB_CHANGED); 447 } 448 } 449 450 if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) && 451 (from->profile_path.string)) { 452 old_string = pdb_get_profile_path(to); 453 new_string = from->profile_path.string; 454 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l, 455 old_string, new_string)); 456 if (STRING_CHANGED) { 457 pdb_set_profile_path(to , new_string, PDB_CHANGED); 458 } 459 } 460 461 if ((from->fields_present & SAMR_FIELD_DESCRIPTION) && 462 (from->description.string)) { 463 old_string = pdb_get_acct_desc(to); 464 new_string = from->description.string; 465 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l, 466 old_string, new_string)); 467 if (STRING_CHANGED) { 468 pdb_set_acct_desc(to, new_string, PDB_CHANGED); 469 } 470 } 471 472 if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) && 473 (from->workstations.string)) { 474 old_string = pdb_get_workstations(to); 475 new_string = from->workstations.string; 476 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l, 477 old_string, new_string)); 478 if (STRING_CHANGED) { 479 pdb_set_workstations(to , new_string, PDB_CHANGED); 480 } 481 } 482 483 if ((from->fields_present & SAMR_FIELD_COMMENT) && 484 (from->comment.string)) { 485 old_string = pdb_get_comment(to); 486 new_string = from->comment.string; 487 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l, 488 old_string, new_string)); 489 if (STRING_CHANGED) { 490 pdb_set_comment(to, new_string, PDB_CHANGED); 491 } 492 } 493 494 if ((from->fields_present & SAMR_FIELD_PARAMETERS) && 495 (from->parameters.array)) { 496 char *newstr; 497 DATA_BLOB mung; 498 old_string = pdb_get_munged_dial(to); 499 500 mung = data_blob_const(from->parameters.array, 501 from->parameters.length); 502 newstr = (mung.length == 0) ? 503 NULL : base64_encode_data_blob(talloc_tos(), mung); 504 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l, 505 old_string, newstr)); 506 if (STRING_CHANGED_NC(old_string,newstr)) { 507 pdb_set_munged_dial(to, newstr, PDB_CHANGED); 508 } 509 510 TALLOC_FREE(newstr); 511 } 512 513 if (from->fields_present & SAMR_FIELD_RID) { 514 if (from->rid == 0) { 515 DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l)); 516 } else if (from->rid != pdb_get_user_rid(to)) { 517 DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l, 518 pdb_get_user_rid(to), from->rid)); 519 } 520 } 521 522 if (from->fields_present & SAMR_FIELD_PRIMARY_GID) { 523 if (from->primary_gid == 0) { 524 DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l)); 525 } else if (from->primary_gid != pdb_get_group_rid(to)) { 526 DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l, 527 pdb_get_group_rid(to), from->primary_gid)); 528 pdb_set_group_sid_from_rid(to, 529 from->primary_gid, PDB_CHANGED); 530 } 531 } 532 533 if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) { 534 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l, 535 pdb_get_acct_ctrl(to), from->acct_flags)); 536 if (from->acct_flags != pdb_get_acct_ctrl(to)) { 537 538 /* You cannot autolock an unlocked account via 539 * setuserinfo calls, so make sure to remove the 540 * ACB_AUTOLOCK bit here - gd */ 541 542 if ((from->acct_flags & ACB_AUTOLOCK) && 543 !(pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) { 544 from->acct_flags &= ~ACB_AUTOLOCK; 545 } 546 547 if (!(from->acct_flags & ACB_AUTOLOCK) && 548 (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) { 549 /* We're unlocking a previously locked user. Reset bad password counts. 550 Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */ 551 pdb_set_bad_password_count(to, 0, PDB_CHANGED); 552 pdb_set_bad_password_time(to, 0, PDB_CHANGED); 553 } 554 pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED); 555 } 556 } 557 558 if (from->fields_present & SAMR_FIELD_LOGON_HOURS) { 559 char oldstr[44]; /* hours strings are 42 bytes. */ 560 char newstr[44]; 561 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l, 562 pdb_get_logon_divs(to), from->logon_hours.units_per_week)); 563 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) { 564 pdb_set_logon_divs(to, 565 from->logon_hours.units_per_week, PDB_CHANGED); 566 } 567 568 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l, 569 pdb_get_hours_len(to), 570 from->logon_hours.units_per_week/8)); 571 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) { 572 pdb_set_hours_len(to, 573 from->logon_hours.units_per_week/8, PDB_CHANGED); 574 } 575 576 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l, 577 pdb_get_hours(to), from->logon_hours.bits)); 578 pdb_sethexhours(oldstr, pdb_get_hours(to)); 579 pdb_sethexhours(newstr, from->logon_hours.bits); 580 if (!strequal(oldstr, newstr)) { 581 pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED); 582 } 583 } 584 585 if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) { 586 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l, 587 pdb_get_bad_password_count(to), from->bad_password_count)); 588 if (from->bad_password_count != pdb_get_bad_password_count(to)) { 589 pdb_set_bad_password_count(to, 590 from->bad_password_count, PDB_CHANGED); 591 } 592 } 593 594 if (from->fields_present & SAMR_FIELD_NUM_LOGONS) { 595 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l, 596 pdb_get_logon_count(to), from->logon_count)); 597 if (from->logon_count != pdb_get_logon_count(to)) { 598 pdb_set_logon_count(to, from->logon_count, PDB_CHANGED); 599 } 600 } 601 602 /* If the must change flag is set, the last set time goes to zero. 603 the must change and can change fields also do, but they are 604 calculated from policy, not set from the wire */ 605 606 if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) { 607 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l, 608 from->password_expired)); 609 if (from->password_expired != 0) { 610 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED); 611 } else { 612 /* A subtlety here: some windows commands will 613 clear the expired flag even though it's not 614 set, and we don't want to reset the time 615 in these caess. "net user /dom <user> /active:y" 616 for example, to clear an autolocked acct. 617 We must check to see if it's expired first. jmcd */ 618 619 uint32_t pwd_max_age = 0; 620 time_t now = time(NULL); 621 622 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age); 623 624 if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { 625 pwd_max_age = get_time_t_max(); 626 } 627 628 stored_time = pdb_get_pass_last_set_time(to); 629 630 /* we will only *set* a pwdlastset date when 631 a) the last pwdlastset time was 0 (user was forced to 632 change password). 633 b) the users password has not expired. gd. */ 634 635 if ((stored_time == 0) || 636 ((now - stored_time) > pwd_max_age)) { 637 pdb_set_pass_last_set_time(to, now, PDB_CHANGED); 638 } 639 } 640 } 641} 642 643 644/************************************************************* 645 Copies a struct samr_UserInfo23 to a struct samu 646**************************************************************/ 647 648void copy_id23_to_sam_passwd(struct samu *to, 649 struct samr_UserInfo23 *from) 650{ 651 if (from == NULL || to == NULL) { 652 return; 653 } 654 655 copy_id21_to_sam_passwd("INFO 23", to, &from->info); 656} 657 658/************************************************************* 659 Copies a struct samr_UserInfo24 to a struct samu 660**************************************************************/ 661 662void copy_id24_to_sam_passwd(struct samu *to, 663 struct samr_UserInfo24 *from) 664{ 665 struct samr_UserInfo21 i; 666 667 if (from == NULL || to == NULL) { 668 return; 669 } 670 671 ZERO_STRUCT(i); 672 673 i.fields_present = SAMR_FIELD_EXPIRED_FLAG; 674 i.password_expired = from->password_expired; 675 676 copy_id21_to_sam_passwd("INFO_24", to, &i); 677} 678 679/************************************************************* 680 Copies a struct samr_UserInfo25 to a struct samu 681**************************************************************/ 682 683void copy_id25_to_sam_passwd(struct samu *to, 684 struct samr_UserInfo25 *from) 685{ 686 if (from == NULL || to == NULL) { 687 return; 688 } 689 690 copy_id21_to_sam_passwd("INFO_25", to, &from->info); 691} 692 693/************************************************************* 694 Copies a struct samr_UserInfo26 to a struct samu 695**************************************************************/ 696 697void copy_id26_to_sam_passwd(struct samu *to, 698 struct samr_UserInfo26 *from) 699{ 700 struct samr_UserInfo21 i; 701 702 if (from == NULL || to == NULL) { 703 return; 704 } 705 706 ZERO_STRUCT(i); 707 708 i.fields_present = SAMR_FIELD_EXPIRED_FLAG; 709 i.password_expired = from->password_expired; 710 711 copy_id21_to_sam_passwd("INFO_26", to, &i); 712} 713