Changeset 77 for trunk/samba/source/smbd/mangle_hash.c
- Timestamp:
- Sep 30, 2007, 3:42:50 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/samba/source/smbd/mangle_hash.c
r1 r77 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Name mangling … … 5 5 Copyright (C) Simo Sorce 2001 6 6 Copyright (C) Andrew Bartlett 2002 7 7 Copyright (C) Jeremy Allison 2007 8 8 9 This program is free software; you can redistribute it and/or modify 9 10 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2of the License, or11 the Free Software Foundation; either version 3 of the License, or 11 12 (at your option) any later version. 12 13 13 14 This program is distributed in the hope that it will be useful, 14 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 17 GNU General Public License for more details. 17 18 18 19 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21 21 */ 22 22 … … 246 246 if (strlen_w(fname) > 12) 247 247 return NT_STATUS_UNSUCCESSFUL; 248 248 249 249 if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0) 250 250 return NT_STATUS_OK; … … 253 253 if (*fname == UCS2_CHAR('.')) 254 254 return NT_STATUS_UNSUCCESSFUL; 255 255 256 256 if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True))) 257 257 goto done; … … 295 295 if (strlen(f) > 12) 296 296 return False; 297 297 298 298 size = push_ucs2_allocate(&ucs2name, f); 299 299 if (size == (size_t)-1) { … … 307 307 SAFE_FREE(ucs2name); 308 308 309 if (!NT_STATUS_IS_OK(ret)) { 310 return False; 311 } 312 309 if (!NT_STATUS_IS_OK(ret)) { 310 return False; 311 } 312 313 313 return True; 314 314 } 315 316 317 315 318 316 /* -------------------------------------------------------------------------- ** … … 332 330 * ************************************************************************** ** 333 331 */ 332 334 333 static void init_chartest( void ) 335 334 { 336 335 const unsigned char *s; 337 336 338 337 memset( (char *)chartest, '\0', 256 ); 339 338 … … 362 361 * ************************************************************************** ** 363 362 */ 363 364 364 static BOOL is_mangled(const char *s, const struct share_params *p) 365 365 { … … 408 408 **************************************************************************/ 409 409 410 static void cache_mangled_name( const char mangled_name[13], char *raw_name ) 410 static void cache_mangled_name( const char mangled_name[13], 411 const char *raw_name ) 411 412 { 412 413 TDB_DATA data_val; … … 438 439 439 440 /* Allocate a new cache entry. If the allocation fails, just return. */ 440 data_val.dptr = raw_name; 441 data_val.dsize = strlen(raw_name)+1; 441 data_val = string_term_tdb_data(raw_name); 442 442 if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) { 443 443 DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name)); … … 462 462 */ 463 463 464 static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p ) 464 static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx, 465 const char *in, 466 char **out, /* talloced on the given context. */ 467 const struct share_params *p) 465 468 { 466 469 TDB_DATA data_val; 467 char *ext_start = NULL;468 470 char *saved_ext = NULL; 471 char *s = talloc_strdup(ctx, in); 469 472 470 473 magic_char = lp_magicchar(p); 471 474 472 475 /* If the cache isn't initialized, give up. */ 473 if( !tdb_mangled_cache ) 474 return( False ); 476 if(!s || !tdb_mangled_cache ) { 477 TALLOC_FREE(s); 478 return False; 479 } 475 480 476 481 data_val = tdb_fetch_bystring(tdb_mangled_cache, s); … … 478 483 /* If we didn't find the name *with* the extension, try without. */ 479 484 if(data_val.dptr == NULL || data_val.dsize == 0) { 480 ext_start = strrchr( s, '.' );485 char *ext_start = strrchr( s, '.' ); 481 486 if( ext_start ) { 482 if((saved_ext = SMB_STRDUP(ext_start)) == NULL) 487 if((saved_ext = talloc_strdup(ctx,ext_start)) == NULL) { 488 TALLOC_FREE(s); 483 489 return False; 490 } 484 491 485 492 *ext_start = '\0'; 486 493 data_val = tdb_fetch_bystring(tdb_mangled_cache, s); 487 /* 494 /* 488 495 * At this point s is the name without the 489 496 * extension. We re-add the extension if saved_ext … … 495 502 /* Okay, if we haven't found it we're done. */ 496 503 if(data_val.dptr == NULL || data_val.dsize == 0) { 497 if(saved_ext) { 498 /* Replace the saved_ext as it was truncated. */ 499 (void)safe_strcat( s, saved_ext, maxlen ); 500 SAFE_FREE(saved_ext); 501 } 502 return( False ); 503 } 504 505 /* If we *did* find it, we need to copy it into the string buffer. */ 506 (void)safe_strcpy( s, data_val.dptr, maxlen ); 507 if( saved_ext ) { 508 /* Replace the saved_ext as it was truncated. */ 509 (void)safe_strcat( s, saved_ext, maxlen ); 510 SAFE_FREE(saved_ext); 511 } 504 TALLOC_FREE(saved_ext); 505 TALLOC_FREE(s); 506 return False; 507 } 508 509 /* If we *did* find it, we need to talloc it on the given ctx. */ 510 if (saved_ext) { 511 *out = talloc_asprintf(ctx, "%s%s", 512 (char *)data_val.dptr, 513 saved_ext); 514 } else { 515 *out = talloc_strdup(ctx, (char *)data_val.dptr); 516 } 517 518 TALLOC_FREE(s); 519 TALLOC_FREE(saved_ext); 512 520 SAFE_FREE(data_val.dptr); 513 return( True ); 521 522 return *out ? True : False; 514 523 } 515 524 516 525 /***************************************************************************** 517 * do the actual mangling to 8.3 format 518 * the buffer must be able to hold 13 characters (including the null) 519 ***************************************************************************** 520 */ 521 static void to_8_3(char *s, int default_case) 526 Do the actual mangling to 8.3 format. 527 *****************************************************************************/ 528 529 static BOOL to_8_3(const char *in, char out[13], int default_case) 522 530 { 523 531 int csum; … … 527 535 int baselen = 0; 528 536 int extlen = 0; 537 char *s = SMB_STRDUP(in); 529 538 530 539 extension[0] = 0; 531 540 base[0] = 0; 532 541 533 p = strrchr(s,'.'); 542 if (!s) { 543 return False; 544 } 545 546 p = strrchr(s,'.'); 534 547 if( p && (strlen(p+1) < (size_t)4) ) { 535 548 BOOL all_normal = ( strisnormal(p+1, default_case) ); /* XXXXXXXXX */ … … 560 573 } 561 574 } 562 575 563 576 p = s; 564 577 … … 570 583 } 571 584 base[baselen] = 0; 572 585 573 586 csum = csum % (MANGLE_BASE*MANGLE_BASE); 574 575 (void)slprintf(s, 12, "%s%c%c%c", 576 base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) ); 577 587 588 memcpy(out, base, baselen); 589 out[baselen] = magic_char; 590 out[baselen+1] = mangle( csum/MANGLE_BASE ); 591 out[baselen+2] = mangle( csum ); 592 578 593 if( *extension ) { 579 (void)pstrcat( s, "." ); 580 (void)pstrcat( s, extension ); 581 } 594 out[baselen+3] = '.'; 595 safe_strcpy(&out[baselen+4], extension, 3); 596 } 597 598 SAFE_FREE(s); 599 return True; 600 } 601 602 static BOOL must_mangle(const char *name, 603 const struct share_params *p) 604 { 605 smb_ucs2_t *name_ucs2 = NULL; 606 NTSTATUS status; 607 magic_char = lp_magicchar(p); 608 609 if (push_ucs2_allocate(&name_ucs2, name) == (size_t)-1) { 610 DEBUG(0, ("push_ucs2_allocate failed!\n")); 611 return False; 612 } 613 status = is_valid_name(name_ucs2, False, False); 614 SAFE_FREE(name_ucs2); 615 return NT_STATUS_IS_OK(status); 582 616 } 583 617 584 618 /***************************************************************************** 585 619 * Convert a filename to DOS format. Return True if successful. 586 * 587 * Input: OutName - Source *and* destination buffer. 588 * 589 * NOTE that OutName must point to a memory space that 590 * is at least 13 bytes in size! 591 * 592 * need83 - If False, name mangling will be skipped unless the 593 * name contains illegal characters. Mapping will still 594 * be done, if appropriate. This is probably used to 595 * signal that a client does not require name mangling, 596 * thus skipping the name mangling even on shares which 597 * have name-mangling turned on. 620 * Input: in Incoming name. 621 * 622 * out 8.3 DOS name. 623 * 598 624 * cache83 - If False, the mangled name cache will not be updated. 599 625 * This is usually used to prevent that we overwrite … … 602 628 * current name. (See PR#13758). UKD. 603 629 * 604 * Output: Returns False only if the name wanted mangling but the share does605 * not have name mangling turned on.606 *607 630 * **************************************************************************** 608 631 */ 609 632 610 static void name_map(char *OutName, BOOL need83, BOOL cache83, 611 int default_case, const struct share_params *p) 612 { 613 smb_ucs2_t *OutName_ucs2; 633 static BOOL hash_name_to_8_3(const char *in, 634 char out[13], 635 BOOL cache83, 636 int default_case, 637 const struct share_params *p) 638 { 639 smb_ucs2_t *in_ucs2 = NULL; 614 640 magic_char = lp_magicchar(p); 615 641 616 DEBUG(5,(" name_map( %s, need83 = %s, cache83 = %s)\n", OutName,617 need83 ? "True" : "False",cache83 ? "True" : "False"));618 619 if (push_ucs2_allocate(& OutName_ucs2, OutName) == (size_t)-1) {642 DEBUG(5,("hash_name_to_8_3( %s, cache83 = %s)\n", in, 643 cache83 ? "True" : "False")); 644 645 if (push_ucs2_allocate(&in_ucs2, in) == (size_t)-1) { 620 646 DEBUG(0, ("push_ucs2_allocate failed!\n")); 621 return; 622 } 623 624 if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False))) 625 need83 = True; 626 627 /* check if it's already in 8.3 format */ 628 if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2, False))) { 629 char *tmp = NULL; 630 631 /* mangle it into 8.3 */ 632 if (cache83) 633 tmp = SMB_STRDUP(OutName); 634 635 to_8_3(OutName, default_case); 636 637 if(tmp != NULL) { 638 cache_mangled_name(OutName, tmp); 639 SAFE_FREE(tmp); 640 } 641 } 642 643 DEBUG(5,("name_map() ==> [%s]\n", OutName)); 644 SAFE_FREE(OutName_ucs2); 647 return False; 648 } 649 650 /* If it's already 8.3, just copy. */ 651 if (NT_STATUS_IS_OK(is_valid_name(in_ucs2, False, False)) && 652 NT_STATUS_IS_OK(is_8_3_w(in_ucs2, False))) { 653 SAFE_FREE(in_ucs2); 654 safe_strcpy(out, in, 12); 655 return True; 656 } 657 658 SAFE_FREE(in_ucs2); 659 if (!to_8_3(in, out, default_case)) { 660 return False; 661 } 662 663 cache_mangled_name(out, in); 664 665 DEBUG(5,("hash_name_to_8_3(%s) ==> [%s]\n", in, out)); 666 return True; 645 667 } 646 668 … … 652 674 mangle_reset, 653 675 is_mangled, 676 must_mangle, 654 677 is_8_3, 655 check_cache,656 name_map678 lookup_name_from_8_3, 679 hash_name_to_8_3 657 680 }; 658 681
Note:
See TracChangeset
for help on using the changeset viewer.