2 Unix SMB/CIFS implementation.
3 filename handling routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1999-2007
6 Copyright (C) Ying Chen 2000
7 Copyright (C) Volker Lendecke 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * New hash table stat cache code added by Ying Chen.
29 static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
30 connection_struct *conn,
31 const char *orig_path,
32 struct smb_filename *smb_fname);
34 /****************************************************************************
35 Mangle the 2nd name and check if it is then equal to the first name.
36 ****************************************************************************/
38 static bool mangled_equal(const char *name1,
40 const struct share_params *p)
44 if (!name_to_8_3(name2, mname, False, p)) {
47 return strequal(name1, mname);
50 /****************************************************************************
51 Cope with the differing wildcard and non-wildcard error cases.
52 ****************************************************************************/
54 static NTSTATUS determine_path_error(const char *name,
55 bool allow_wcard_last_component)
59 if (!allow_wcard_last_component) {
60 /* Error code within a pathname. */
61 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
64 /* We're terminating here so we
65 * can be a little slower and get
66 * the error code right. Windows
67 * treats the last part of the pathname
68 * separately I think, so if the last
69 * component is a wildcard then we treat
70 * this ./ as "end of component" */
72 p = strchr(name, '/');
74 if (!p && (ms_has_wild(name) || ISDOT(name))) {
75 /* Error code at the end of a pathname. */
76 return NT_STATUS_OBJECT_NAME_INVALID;
78 /* Error code within a pathname. */
79 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
84 * XXX: This is temporary and there should be no callers of this outside of
85 * this file once smb_filename is plumbed through all path based operations.
86 * The one legitimate caller currently is smb_fname_str_dbg(), which this
87 * could be made static for.
89 NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
92 if (smb_fname->stream_name) {
93 *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
94 smb_fname->stream_name);
96 *full_name = talloc_strdup(ctx, smb_fname->base_name);
100 return NT_STATUS_NO_MEMORY;
107 * There are actually legitimate callers of this such as functions that
108 * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
109 * operate on each stream.
111 NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
112 const char *stream_name,
113 SMB_STRUCT_STAT *psbuf,
114 struct smb_filename **smb_fname_out)
116 struct smb_filename smb_fname_loc;
120 ZERO_STRUCT(smb_fname_loc);
122 /* Setup the base_name/stream_name. */
123 smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
124 smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
126 /* Copy the psbuf if one was given. */
127 smb_fname_loc.st = *psbuf;
129 /* Let copy_smb_filename() do the heavy lifting. */
130 return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
134 * XXX: This is temporary and there should be no callers of this once
135 * smb_filename is plumbed through all path based operations.
137 NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
139 SMB_STRUCT_STAT *psbuf,
140 struct smb_filename **smb_fname_out)
143 const char *stream_name = NULL;
144 char *base_name = NULL;
146 /* Setup the base_name/stream_name. */
147 stream_name = strchr_m(fname, ':');
149 base_name = talloc_strndup(ctx, fname,
150 PTR_DIFF(stream_name, fname));
152 base_name = talloc_strdup(ctx, fname);
156 return NT_STATUS_NO_MEMORY;
159 status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
161 TALLOC_FREE(base_name);
166 * Return a string using the debug_ctx()
168 char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
173 status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
174 if (!NT_STATUS_IS_OK(status)) {
175 fname = talloc_strdup(debug_ctx(), "");
180 NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
181 const struct smb_filename *smb_fname_in,
182 struct smb_filename **smb_fname_out)
185 *smb_fname_out = talloc_zero(ctx, struct smb_filename);
186 if (*smb_fname_out == NULL) {
187 return NT_STATUS_NO_MEMORY;
190 if (smb_fname_in->base_name) {
191 (*smb_fname_out)->base_name =
192 talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
193 if (!(*smb_fname_out)->base_name)
197 if (smb_fname_in->stream_name) {
198 (*smb_fname_out)->stream_name =
199 talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
200 if (!(*smb_fname_out)->stream_name)
204 if (smb_fname_in->original_lcomp) {
205 (*smb_fname_out)->original_lcomp =
206 talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
207 if (!(*smb_fname_out)->original_lcomp)
211 (*smb_fname_out)->st = smb_fname_in->st;
215 TALLOC_FREE(*smb_fname_out);
216 return NT_STATUS_NO_MEMORY;
219 /****************************************************************************
220 This routine is called to convert names from the dos namespace to unix
221 namespace. It needs to handle any case conversions, mangling, format changes,
224 We assume that we have already done a chdir() to the right "root" directory
227 The function will return an NTSTATUS error if some part of the name except for
228 the last part cannot be resolved, else NT_STATUS_OK.
230 Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we
231 didn't get any fatal errors that should immediately terminate the calling SMB
232 processing whilst resolving.
234 If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component
235 of the pathname is set in smb_filename->original_lcomp.
237 If UCF_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected and
238 should be allowed in the last component of the path only.
240 If the orig_path was a stream, smb_filename->base_name will point to the base
241 filename, and smb_filename->stream_name will point to the stream name. If
242 orig_path was not a stream, then smb_filename->stream_name will be NULL.
244 On exit from unix_convert, the smb_filename->st stat struct will be populated
245 if the file exists and was found, if not this stat struct will be filled with
246 zeros (and this can be detected by checking for nlinks = 0, which can never be
248 ****************************************************************************/
250 NTSTATUS unix_convert(TALLOC_CTX *ctx,
251 connection_struct *conn,
252 const char *orig_path,
253 struct smb_filename **smb_fname_out,
257 struct smb_filename *smb_fname = NULL;
259 char *dirpath = NULL;
262 bool component_was_mangled = False;
263 bool name_has_wildcard = False;
264 bool posix_pathnames = false;
265 bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
266 bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
270 *smb_fname_out = NULL;
272 smb_fname = talloc_zero(talloc_tos(), struct smb_filename);
273 if (smb_fname == NULL) {
274 return NT_STATUS_NO_MEMORY;
278 /* we don't ever use the filenames on a printer share as a
279 filename - so don't convert them */
280 if (!(smb_fname->base_name = talloc_strdup(smb_fname,
282 return NT_STATUS_NO_MEMORY;
284 *smb_fname_out = smb_fname;
288 DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
291 * Conversion to basic unix format is already done in
292 * check_path_syntax().
296 * Names must be relative to the root of the service - any leading /.
297 * and trailing /'s should have been trimmed by check_path_syntax().
301 SMB_ASSERT(*orig_path != '/');
305 * If we trimmed down to a single '\0' character
306 * then we should use the "." directory to avoid
307 * searching the cache, but not if we are in a
309 * As we know this is valid we can return true here.
313 if (!(name = talloc_strdup(ctx,"."))) {
314 return NT_STATUS_NO_MEMORY;
316 if (SMB_VFS_STAT(conn,name,&st) == 0) {
319 return map_nt_error_from_unix(errno);
321 DEBUG(5,("conversion finished \"\" -> %s\n",name));
325 if (orig_path[0] == '.' && (orig_path[1] == '/' ||
326 orig_path[1] == '\0')) {
327 /* Start of pathname can't be "." only. */
328 if (orig_path[1] == '\0' || orig_path[2] == '\0') {
329 result = NT_STATUS_OBJECT_NAME_INVALID;
331 result =determine_path_error(
332 &orig_path[2], allow_wcard_last_component);
337 if (!(name = talloc_strdup(ctx, orig_path))) {
338 DEBUG(0, ("talloc_strdup failed\n"));
339 return NT_STATUS_NO_MEMORY;
343 * Large directory fix normalization. If we're case sensitive, and
344 * the case preserving parameters are set to "no", normalize the case of
345 * the incoming filename from the client WHETHER IT EXISTS OR NOT !
346 * This is in conflict with the current (3.0.20) man page, but is
347 * what people expect from the "large directory howto". I'll update
348 * the man page. Thanks to jht@samba.org for finding this. JRA.
351 if (conn->case_sensitive && !conn->case_preserve &&
352 !conn->short_case_preserve) {
353 strnorm(name, lp_defaultcase(SNUM(conn)));
357 * Ensure saved_last_component is valid even if file exists.
360 if(save_last_component) {
361 end = strrchr_m(name, '/');
363 smb_fname->original_lcomp = talloc_strdup(ctx,
366 smb_fname->original_lcomp = talloc_strdup(ctx, name);
370 posix_pathnames = lp_posix_pathnames();
372 /* Strip off the stream. Should we use any of the other stream parsing
373 * at this point? Also, should we set the is_stream bit? */
374 if (!posix_pathnames) {
375 stream = strchr_m(name, ':');
377 if (stream != NULL) {
378 char *tmp = talloc_strdup(ctx, stream);
381 return NT_STATUS_NO_MEMORY;
390 /* If we're providing case insentive semantics or
391 * the underlying filesystem is case insensitive,
392 * then a case-normalized hit in the stat-cache is
393 * authoratitive. JRA.
396 if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
397 stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
403 * Make sure "dirpath" is an allocated string, we use this for
404 * building the directories with asprintf and free it.
407 if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
408 DEBUG(0, ("talloc_strdup failed\n"));
410 return NT_STATUS_NO_MEMORY;
414 * stat the name - if it exists then we are all done!
417 if (posix_pathnames) {
418 ret = SMB_VFS_LSTAT(conn,name,&st);
420 ret = SMB_VFS_STAT(conn,name,&st);
424 /* Ensure we catch all names with in "/."
425 this is disallowed under Windows. */
426 const char *p = strstr(name, "/."); /* mb safe. */
429 /* Error code within a pathname. */
430 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
432 } else if (p[2] == '\0') {
433 /* Error code at the end of a pathname. */
434 result = NT_STATUS_OBJECT_NAME_INVALID;
438 stat_cache_add(orig_path, name, conn->case_sensitive);
439 DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
444 DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
445 name, dirpath, start));
448 * A special case - if we don't have any mangling chars and are case
449 * sensitive or the underlying filesystem is case insentive then searching
453 if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
454 !mangle_is_mangled(name, conn->params)) {
459 * is_mangled() was changed to look at an entire pathname, not
460 * just a component. JRA.
463 if (mangle_is_mangled(start, conn->params)) {
464 component_was_mangled = True;
468 * Now we need to recursively match the name against the real
469 * directory structure.
473 * Match each part of the path name separately, trying the names
474 * as is first, then trying to scan the directory for matching names.
477 for (; start ; start = (end?end+1:(char *)NULL)) {
479 * Pinpoint the end of this section of the filename.
481 /* mb safe. '/' can't be in any encoded char. */
482 end = strchr(start, '/');
485 * Chop the name at this point.
491 if (save_last_component) {
492 TALLOC_FREE(smb_fname->original_lcomp);
493 smb_fname->original_lcomp = talloc_strdup(ctx,
494 end ? end + 1 : start);
495 if (!smb_fname->original_lcomp) {
496 DEBUG(0, ("talloc failed\n"));
497 return NT_STATUS_NO_MEMORY;
501 /* The name cannot have a component of "." */
505 /* Error code at the end of a pathname. */
506 result = NT_STATUS_OBJECT_NAME_INVALID;
508 result = determine_path_error(end+1,
509 allow_wcard_last_component);
514 /* The name cannot have a wildcard if it's not
515 the last component. */
517 name_has_wildcard = ms_has_wild(start);
519 /* Wildcard not valid anywhere. */
520 if (name_has_wildcard && !allow_wcard_last_component) {
521 result = NT_STATUS_OBJECT_NAME_INVALID;
525 /* Wildcards never valid within a pathname. */
526 if (name_has_wildcard && end) {
527 result = NT_STATUS_OBJECT_NAME_INVALID;
532 * Check if the name exists up to this point.
535 if (posix_pathnames) {
536 ret = SMB_VFS_LSTAT(conn,name, &st);
538 ret = SMB_VFS_STAT(conn,name, &st);
543 * It exists. it must either be a directory or this must
544 * be the last part of the path for it to be OK.
546 if (end && !S_ISDIR(st.st_ex_mode)) {
548 * An intermediate part of the name isn't
551 DEBUG(5,("Not a dir %s\n",start));
554 * We need to return the fact that the
555 * intermediate name resolution failed. This
556 * is used to return an error of ERRbadpath
557 * rather than ERRbadfile. Some Windows
558 * applications depend on the difference between
561 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
567 * We just scanned for, and found the end of
568 * the path. We must return the valid stat
576 char *found_name = NULL;
578 /* Stat failed - ensure we don't use it. */
579 SET_STAT_INVALID(st);
582 * Reset errno so we can detect
583 * directory open errors.
588 * Try to find this part of the path in the directory.
591 if (name_has_wildcard ||
592 (get_real_filename(conn, dirpath, start,
594 &found_name) == -1)) {
599 * An intermediate part of the name
602 DEBUG(5,("Intermediate not found %s\n",
607 * We need to return the fact that the
608 * intermediate name resolution failed.
609 * This is used to return an error of
610 * ERRbadpath rather than ERRbadfile.
611 * Some Windows applications depend on
612 * the difference between these two
617 * ENOENT, ENOTDIR and ELOOP all map
618 * to NT_STATUS_OBJECT_PATH_NOT_FOUND
619 * in the filename walk.
622 if (errno == ENOENT ||
626 NT_STATUS_OBJECT_PATH_NOT_FOUND;
630 map_nt_error_from_unix(errno);
636 * ENOENT/EACCESS are the only valid errors
637 * here. EACCESS needs handling here for
638 * "dropboxes", i.e. directories where users
639 * can only put stuff with permission -wx.
641 if ((errno != 0) && (errno != ENOENT)
642 && (errno != EACCES)) {
644 * ENOTDIR and ELOOP both map to
645 * NT_STATUS_OBJECT_PATH_NOT_FOUND
646 * in the filename walk.
648 if (errno == ENOTDIR ||
651 NT_STATUS_OBJECT_PATH_NOT_FOUND;
654 map_nt_error_from_unix(errno);
660 * Just the last part of the name doesn't exist.
661 * We need to strupper() or strlower() it as
662 * this conversion may be used for file creation
663 * purposes. Fix inspired by
664 * Thomas Neumann <t.neumann@iku-ag.de>.
666 if (!conn->case_preserve ||
667 (mangle_is_8_3(start, False,
669 !conn->short_case_preserve)) {
671 lp_defaultcase(SNUM(conn)));
675 * check on the mangled stack to see if we can
676 * recover the base of the filename.
679 if (mangle_is_mangled(start, conn->params)
680 && mangle_lookup_name_from_8_3(ctx,
685 size_t start_ofs = start - name;
687 if (*dirpath != '\0') {
688 tmp = talloc_asprintf(ctx,
691 TALLOC_FREE(unmangled);
697 DEBUG(0, ("talloc failed\n"));
698 return NT_STATUS_NO_MEMORY;
702 start = name + start_ofs;
703 end = start + strlen(start);
706 DEBUG(5,("New file %s\n",start));
712 * Restore the rest of the string. If the string was
713 * mangled the size may have changed.
717 size_t start_ofs = start - name;
719 if (*dirpath != '\0') {
720 tmp = talloc_asprintf(ctx,
725 tmp = talloc_asprintf(ctx,
730 DEBUG(0, ("talloc_asprintf failed\n"));
731 return NT_STATUS_NO_MEMORY;
735 start = name + start_ofs;
736 end = start + strlen(found_name);
740 size_t start_ofs = start - name;
742 if (*dirpath != '\0') {
743 tmp = talloc_asprintf(ctx,
747 tmp = talloc_strdup(ctx,
751 DEBUG(0, ("talloc failed\n"));
752 return NT_STATUS_NO_MEMORY;
756 start = name + start_ofs;
759 * We just scanned for, and found the end of
760 * the path. We must return a valid stat struct
764 if (posix_pathnames) {
765 ret = SMB_VFS_LSTAT(conn,name, &st);
767 ret = SMB_VFS_STAT(conn,name, &st);
773 SET_STAT_INVALID(st);
777 TALLOC_FREE(found_name);
783 * We should never provide different behaviors
784 * depending on DEVELOPER!!!
786 if (VALID_STAT(st)) {
788 get_file_infos(vfs_file_id_from_sbuf(conn, &st),
789 &delete_pending, NULL);
790 if (delete_pending) {
791 result = NT_STATUS_DELETE_PENDING;
798 * Add to the dirpath that we have resolved so far.
801 if (*dirpath != '\0') {
802 char *tmp = talloc_asprintf(ctx,
803 "%s/%s", dirpath, start);
805 DEBUG(0, ("talloc_asprintf failed\n"));
806 return NT_STATUS_NO_MEMORY;
808 TALLOC_FREE(dirpath);
812 TALLOC_FREE(dirpath);
813 if (!(dirpath = talloc_strdup(ctx,start))) {
814 DEBUG(0, ("talloc_strdup failed\n"));
815 return NT_STATUS_NO_MEMORY;
820 * Don't cache a name with mangled or wildcard components
821 * as this can change the size.
824 if(!component_was_mangled && !name_has_wildcard) {
825 stat_cache_add(orig_path, dirpath,
826 conn->case_sensitive);
830 * Restore the / that we wiped out earlier.
838 * Don't cache a name with mangled or wildcard components
839 * as this can change the size.
842 if(!component_was_mangled && !name_has_wildcard) {
843 stat_cache_add(orig_path, name, conn->case_sensitive);
847 * The name has been resolved.
850 DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
853 smb_fname->base_name = name;
855 if (stream != NULL) {
856 smb_fname->stream_name = stream;
858 /* Check path now that the base_name has been converted. */
859 result = build_stream_path(ctx, conn, orig_path, smb_fname);
860 if (!NT_STATUS_IS_OK(result)) {
864 TALLOC_FREE(dirpath);
865 *smb_fname_out = smb_fname;
868 DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
869 if (*dirpath != '\0') {
870 smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath,
873 smb_fname->base_name = talloc_strdup(ctx, start);
875 if (!smb_fname->base_name) {
876 DEBUG(0, ("talloc_asprintf failed\n"));
877 return NT_STATUS_NO_MEMORY;
880 *smb_fname_out = smb_fname;
882 TALLOC_FREE(dirpath);
886 /****************************************************************************
887 Check a filename - possibly calling check_reduced_name.
888 This is called by every routine before it allows an operation on a filename.
889 It does any final confirmation necessary to ensure that the filename is
890 a valid one for the user to access.
891 ****************************************************************************/
893 NTSTATUS check_name(connection_struct *conn, const char *name)
895 if (IS_VETO_PATH(conn, name)) {
896 /* Is it not dot or dot dot. */
897 if (!((name[0] == '.') && (!name[1] ||
898 (name[1] == '.' && !name[2])))) {
899 DEBUG(5,("check_name: file path name %s vetoed\n",
901 return map_nt_error_from_unix(ENOENT);
905 if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) {
906 NTSTATUS status = check_reduced_name(conn,name);
907 if (!NT_STATUS_IS_OK(status)) {
908 DEBUG(5,("check_name: name %s failed with %s\n",name,
917 /****************************************************************************
918 Check if two filenames are equal.
919 This needs to be careful about whether we are case sensitive.
920 ****************************************************************************/
922 static bool fname_equal(const char *name1, const char *name2,
925 /* Normal filename handling */
926 if (case_sensitive) {
927 return(strcmp(name1,name2) == 0);
930 return(strequal(name1,name2));
933 /****************************************************************************
934 Scan a directory to find a filename, matching without case sensitivity.
935 If the name looks like a mangled name then try via the mangling functions
936 ****************************************************************************/
938 static int get_real_filename_full_scan(connection_struct *conn,
939 const char *path, const char *name,
941 TALLOC_CTX *mem_ctx, char **found_name)
943 struct smb_Dir *cur_dir;
945 char *unmangled_name = NULL;
948 /* handle null paths */
949 if ((path == NULL) || (*path == 0)) {
953 /* If we have a case-sensitive filesystem, it doesn't do us any
954 * good to search for a name. If a case variation of the name was
955 * there, then the original stat(2) would have found it.
957 if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) {
963 * The incoming name can be mangled, and if we de-mangle it
964 * here it will not compare correctly against the filename (name2)
965 * read from the directory and then mangled by the name_to_8_3()
966 * call. We need to mangle both names or neither.
969 * Fix for bug found by Dina Fine. If in case sensitive mode then
970 * the mangle cache is no good (3 letter extension could be wrong
971 * case - so don't demangle in this case - leave as mangled and
972 * allow the mangling of the directory entry read (which is done
973 * case insensitively) to match instead. This will lead to more
974 * false positive matches but we fail completely without it. JRA.
977 if (mangled && !conn->case_sensitive) {
978 mangled = !mangle_lookup_name_from_8_3(talloc_tos(), name,
982 /* Name is now unmangled. */
983 name = unmangled_name;
987 /* open the directory */
988 if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) {
989 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
990 TALLOC_FREE(unmangled_name);
994 /* now scan for matching names */
996 while ((dname = ReadDirName(cur_dir, &curpos, NULL))) {
998 /* Is it dot or dot dot. */
999 if (ISDOT(dname) || ISDOTDOT(dname)) {
1004 * At this point dname is the unmangled name.
1005 * name is either mangled or not, depending on the state
1006 * of the "mangled" variable. JRA.
1010 * Check mangled name against mangled name, or unmangled name
1011 * against unmangled name.
1014 if ((mangled && mangled_equal(name,dname,conn->params)) ||
1015 fname_equal(name, dname, conn->case_sensitive)) {
1016 /* we've found the file, change it's name and return */
1017 *found_name = talloc_strdup(mem_ctx, dname);
1018 TALLOC_FREE(unmangled_name);
1019 TALLOC_FREE(cur_dir);
1028 TALLOC_FREE(unmangled_name);
1029 TALLOC_FREE(cur_dir);
1034 /****************************************************************************
1035 Wrapper around the vfs get_real_filename and the full directory scan
1037 ****************************************************************************/
1039 int get_real_filename(connection_struct *conn, const char *path,
1040 const char *name, TALLOC_CTX *mem_ctx,
1046 mangled = mangle_is_mangled(name, conn->params);
1049 return get_real_filename_full_scan(conn, path, name, mangled,
1050 mem_ctx, found_name);
1053 /* Try the vfs first to take advantage of case-insensitive stat. */
1054 ret = SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name);
1057 * If the case-insensitive stat was successful, or returned an error
1058 * other than EOPNOTSUPP then there is no need to fall back on the
1059 * full directory scan.
1061 if (ret == 0 || (ret == -1 && errno != EOPNOTSUPP)) {
1065 return get_real_filename_full_scan(conn, path, name, mangled, mem_ctx,
1069 static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
1070 connection_struct *conn,
1071 const char *orig_path,
1072 struct smb_filename *smb_fname)
1074 char *result = NULL;
1076 unsigned int i, num_streams;
1077 struct stream_struct *streams = NULL;
1079 status = get_full_smb_filename(mem_ctx, smb_fname, &result);
1080 if (!NT_STATUS_IS_OK(status)) {
1081 return NT_STATUS_NO_MEMORY;
1084 if (SMB_VFS_STAT(conn, result, &smb_fname->st) == 0) {
1085 return NT_STATUS_OK;
1088 if (errno != ENOENT) {
1089 status = map_nt_error_from_unix(errno);
1090 DEBUG(10, ("vfs_stat failed: %s\n", nt_errstr(status)));
1094 /* Fall back to a case-insensitive scan of all streams on the file. */
1095 status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, mem_ctx,
1096 &num_streams, &streams);
1098 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1099 SET_STAT_INVALID(smb_fname->st);
1100 return NT_STATUS_OK;
1103 if (!NT_STATUS_IS_OK(status)) {
1104 DEBUG(10, ("vfs_streaminfo failed: %s\n", nt_errstr(status)));
1108 for (i=0; i<num_streams; i++) {
1109 DEBUG(10, ("comparing [%s] and [%s]: ",
1110 smb_fname->stream_name, streams[i].name));
1111 if (fname_equal(smb_fname->stream_name, streams[i].name,
1112 conn->case_sensitive)) {
1113 DEBUGADD(10, ("equal\n"));
1116 DEBUGADD(10, ("not equal\n"));
1119 /* Couldn't find the stream. */
1120 if (i == num_streams) {
1121 SET_STAT_INVALID(smb_fname->st);
1122 TALLOC_FREE(streams);
1123 return NT_STATUS_OK;
1126 DEBUG(10, ("case insensitive stream. requested: %s, actual: %s\n",
1127 smb_fname->stream_name, streams[i].name));
1130 TALLOC_FREE(smb_fname->stream_name);
1131 smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name);
1133 TALLOC_FREE(result);
1134 status = get_full_smb_filename(mem_ctx, smb_fname, &result);
1135 if (!NT_STATUS_IS_OK(status)) {
1136 status = NT_STATUS_NO_MEMORY;
1140 SET_STAT_INVALID(smb_fname->st);
1142 if (SMB_VFS_STAT(conn, result, &smb_fname->st) == 0) {
1143 stat_cache_add(orig_path, result, conn->case_sensitive);
1146 TALLOC_FREE(streams);
1147 return NT_STATUS_OK;
1150 TALLOC_FREE(result);
1151 TALLOC_FREE(streams);