Changeset 745 for trunk/server/source3/smbd/filename.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/filename.c
r599 r745 26 26 27 27 #include "includes.h" 28 #include "system/filesys.h" 29 #include "fake_file.h" 30 #include "smbd/smbd.h" 28 31 29 32 static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, … … 96 99 } 97 100 } 101 return NT_STATUS_OK; 102 } 103 104 /**************************************************************************** 105 Optimization for common case where the missing part 106 is in the last component and the client already 107 sent the correct case. 108 Returns NT_STATUS_OK to mean continue the tree walk 109 (possibly with modified start pointer). 110 Any other NT_STATUS_XXX error means terminate the path 111 lookup here. 112 ****************************************************************************/ 113 114 static NTSTATUS check_parent_exists(TALLOC_CTX *ctx, 115 connection_struct *conn, 116 bool posix_pathnames, 117 const struct smb_filename *smb_fname, 118 char **pp_dirpath, 119 char **pp_start) 120 { 121 struct smb_filename parent_fname; 122 const char *last_component = NULL; 123 NTSTATUS status; 124 int ret; 125 126 ZERO_STRUCT(parent_fname); 127 if (!parent_dirname(ctx, smb_fname->base_name, 128 &parent_fname.base_name, 129 &last_component)) { 130 return NT_STATUS_NO_MEMORY; 131 } 132 133 /* 134 * If there was no parent component in 135 * smb_fname->base_name of the parent name 136 * contained a wildcard then don't do this 137 * optimization. 138 */ 139 if ((smb_fname->base_name == last_component) || 140 ms_has_wild(parent_fname.base_name)) { 141 return NT_STATUS_OK; 142 } 143 144 if (posix_pathnames) { 145 ret = SMB_VFS_LSTAT(conn, &parent_fname); 146 } else { 147 ret = SMB_VFS_STAT(conn, &parent_fname); 148 } 149 150 /* If the parent stat failed, just continue 151 with the normal tree walk. */ 152 153 if (ret == -1) { 154 return NT_STATUS_OK; 155 } 156 157 status = check_for_dot_component(&parent_fname); 158 if (!NT_STATUS_IS_OK(status)) { 159 return status; 160 } 161 162 /* Parent exists - set "start" to be the 163 * last compnent to shorten the tree walk. */ 164 165 /* 166 * Safe to use CONST_DISCARD 167 * here as last_component points 168 * into our smb_fname->base_name. 169 */ 170 *pp_start = CONST_DISCARD(char *,last_component); 171 172 /* Update dirpath. */ 173 TALLOC_FREE(*pp_dirpath); 174 *pp_dirpath = talloc_strdup(ctx, parent_fname.base_name); 175 if (!*pp_dirpath) { 176 return NT_STATUS_NO_MEMORY; 177 } 178 179 DEBUG(5,("check_parent_exists: name " 180 "= %s, dirpath = %s, " 181 "start = %s\n", 182 smb_fname->base_name, 183 *pp_dirpath, 184 *pp_start)); 185 98 186 return NT_STATUS_OK; 99 187 } … … 285 373 286 374 /* 287 * If we're providing case insen tive semantics or375 * If we're providing case insensitive semantics or 288 376 * the underlying filesystem is case insensitive, 289 377 * then a case-normalized hit in the stat-cache is … … 303 391 /* 304 392 * Make sure "dirpath" is an allocated string, we use this for 305 * building the directories with asprintf and free it.393 * building the directories with talloc_asprintf and free it. 306 394 */ 307 395 … … 356 444 SET_STAT_INVALID(smb_fname->st); 357 445 446 if (errno == ENOENT) { 447 /* Optimization when creating a new file - only 448 the last component doesn't exist. */ 449 status = check_parent_exists(ctx, 450 conn, 451 posix_pathnames, 452 smb_fname, 453 &dirpath, 454 &start); 455 if (!NT_STATUS_IS_OK(status)) { 456 goto fail; 457 } 458 } 459 358 460 /* 359 461 * A special case - if we don't have any wildcards or mangling chars and are case 360 * sensitive or the underlying filesystem is case insen tive then searching462 * sensitive or the underlying filesystem is case insensitive then searching 361 463 * won't help. 362 464 */ … … 385 487 */ 386 488 struct smb_filename parent_fname; 489 const char *last_component = NULL; 490 387 491 ZERO_STRUCT(parent_fname); 388 492 if (!parent_dirname(ctx, smb_fname->base_name, 389 493 &parent_fname.base_name, 390 NULL)) {494 &last_component)) { 391 495 status = NT_STATUS_NO_MEMORY; 392 496 goto fail; … … 405 509 } 406 510 } 511 407 512 /* 408 513 * Missing last component is ok - new file. … … 412 517 goto done; 413 518 } 519 } 520 } else { 521 /* 522 * We have a wildcard in the pathname. 523 * 524 * Optimization for common case where the wildcard 525 * is in the last component and the client already 526 * sent the correct case. 527 */ 528 status = check_parent_exists(ctx, 529 conn, 530 posix_pathnames, 531 smb_fname, 532 &dirpath, 533 &start); 534 if (!NT_STATUS_IS_OK(status)) { 535 goto fail; 414 536 } 415 537 } … … 481 603 status = NT_STATUS_OBJECT_NAME_INVALID; 482 604 goto fail; 605 } 606 607 /* Skip the stat call if it's a wildcard end. */ 608 if (name_has_wildcard) { 609 DEBUG(5,("Wildcard %s\n",start)); 610 goto done; 483 611 } 484 612 … … 735 863 if (VALID_STAT(smb_fname->st)) { 736 864 bool delete_pending; 865 uint32_t name_hash; 866 867 status = file_name_hash(conn, 868 smb_fname_str_dbg(smb_fname), 869 &name_hash); 870 if (!NT_STATUS_IS_OK(status)) { 871 goto fail; 872 } 873 737 874 get_file_infos(vfs_file_id_from_sbuf(conn, 738 875 &smb_fname->st), 876 name_hash, 739 877 &delete_pending, NULL); 740 878 if (delete_pending) {
Note:
See TracChangeset
for help on using the changeset viewer.