s3: smbd: Remove unused parameter from build_stream_path().
[vlendec/samba-autobuild/.git] / source3 / smbd / filename.c
1 /*
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
8
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.
13
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.
18
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/>.
21 */
22
23 /*
24  * New hash table stat cache code added by Ying Chen.
25  */
26
27 #include "includes.h"
28 #include "system/filesys.h"
29 #include "fake_file.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32
33 static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
34                                   connection_struct *conn,
35                                   struct smb_filename *smb_fname);
36
37 /****************************************************************************
38  Mangle the 2nd name and check if it is then equal to the first name.
39 ****************************************************************************/
40
41 static bool mangled_equal(const char *name1,
42                         const char *name2,
43                         const struct share_params *p)
44 {
45         char mname[13];
46
47         if (!name_to_8_3(name2, mname, False, p)) {
48                 return False;
49         }
50         return strequal(name1, mname);
51 }
52
53 /****************************************************************************
54  Cope with the differing wildcard and non-wildcard error cases.
55 ****************************************************************************/
56
57 static NTSTATUS determine_path_error(const char *name,
58                         bool allow_wcard_last_component)
59 {
60         const char *p;
61
62         if (!allow_wcard_last_component) {
63                 /* Error code within a pathname. */
64                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
65         }
66
67         /* We're terminating here so we
68          * can be a little slower and get
69          * the error code right. Windows
70          * treats the last part of the pathname
71          * separately I think, so if the last
72          * component is a wildcard then we treat
73          * this ./ as "end of component" */
74
75         p = strchr(name, '/');
76
77         if (!p && (ms_has_wild(name) || ISDOT(name))) {
78                 /* Error code at the end of a pathname. */
79                 return NT_STATUS_OBJECT_NAME_INVALID;
80         } else {
81                 /* Error code within a pathname. */
82                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
83         }
84 }
85
86 static NTSTATUS check_for_dot_component(const struct smb_filename *smb_fname)
87 {
88         /* Ensure we catch all names with in "/."
89            this is disallowed under Windows and
90            in POSIX they've already been removed. */
91         const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
92         if (p) {
93                 if (p[2] == '/') {
94                         /* Error code within a pathname. */
95                         return NT_STATUS_OBJECT_PATH_NOT_FOUND;
96                 } else if (p[2] == '\0') {
97                         /* Error code at the end of a pathname. */
98                         return NT_STATUS_OBJECT_NAME_INVALID;
99                 }
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 component to shorten the tree walk. */
164
165         /*
166          * Safe to use discard_const_p
167          * here as last_component points
168          * into our smb_fname->base_name.
169          */
170         *pp_start = discard_const_p(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
186         return NT_STATUS_OK;
187 }
188
189 /****************************************************************************
190 This routine is called to convert names from the dos namespace to unix
191 namespace. It needs to handle any case conversions, mangling, format changes,
192 streams etc.
193
194 We assume that we have already done a chdir() to the right "root" directory
195 for this service.
196
197 The function will return an NTSTATUS error if some part of the name except for
198 the last part cannot be resolved, else NT_STATUS_OK.
199
200 Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we
201 didn't get any fatal errors that should immediately terminate the calling SMB
202 processing whilst resolving.
203
204 If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component
205 of the pathname is set in smb_filename->original_lcomp.
206
207 If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected
208 and should be allowed in the last component of the path only.
209
210 If the orig_path was a stream, smb_filename->base_name will point to the base
211 filename, and smb_filename->stream_name will point to the stream name.  If
212 orig_path was not a stream, then smb_filename->stream_name will be NULL.
213
214 On exit from unix_convert, the smb_filename->st stat struct will be populated
215 if the file exists and was found, if not this stat struct will be filled with
216 zeros (and this can be detected by checking for nlinks = 0, which can never be
217 true for any file).
218 ****************************************************************************/
219
220 NTSTATUS unix_convert(TALLOC_CTX *ctx,
221                       connection_struct *conn,
222                       const char *orig_path,
223                       struct smb_filename **smb_fname_out,
224                       uint32_t ucf_flags)
225 {
226         struct smb_filename *smb_fname = NULL;
227         char *start, *end;
228         char *dirpath = NULL;
229         char *stream = NULL;
230         bool component_was_mangled = False;
231         bool name_has_wildcard = False;
232         bool posix_pathnames = false;
233         bool allow_wcard_last_component =
234             (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP);
235         bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
236         NTSTATUS status;
237         int ret = -1;
238
239         *smb_fname_out = NULL;
240
241         smb_fname = talloc_zero(ctx, struct smb_filename);
242         if (smb_fname == NULL) {
243                 return NT_STATUS_NO_MEMORY;
244         }
245
246         if (conn->printer) {
247                 /* we don't ever use the filenames on a printer share as a
248                         filename - so don't convert them */
249                 if (!(smb_fname->base_name = talloc_strdup(smb_fname,
250                                                            orig_path))) {
251                         status = NT_STATUS_NO_MEMORY;
252                         goto err;
253                 }
254                 goto done;
255         }
256
257         DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
258
259         /*
260          * Conversion to basic unix format is already done in
261          * check_path_syntax().
262          */
263
264         /*
265          * Names must be relative to the root of the service - any leading /.
266          * and trailing /'s should have been trimmed by check_path_syntax().
267          */
268
269 #ifdef DEVELOPER
270         SMB_ASSERT(*orig_path != '/');
271 #endif
272
273         /*
274          * If we trimmed down to a single '\0' character
275          * then we should use the "." directory to avoid
276          * searching the cache, but not if we are in a
277          * printing share.
278          * As we know this is valid we can return true here.
279          */
280
281         if (!*orig_path) {
282                 if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) {
283                         status = NT_STATUS_NO_MEMORY;
284                         goto err;
285                 }
286                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
287                         status = map_nt_error_from_unix(errno);
288                         goto err;
289                 }
290                 DEBUG(5, ("conversion finished \"\" -> %s\n",
291                           smb_fname->base_name));
292                 goto done;
293         }
294
295         if (orig_path[0] == '.' && (orig_path[1] == '/' ||
296                                 orig_path[1] == '\0')) {
297                 /* Start of pathname can't be "." only. */
298                 if (orig_path[1] == '\0' || orig_path[2] == '\0') {
299                         status = NT_STATUS_OBJECT_NAME_INVALID;
300                 } else {
301                         status =determine_path_error(&orig_path[2],
302                             allow_wcard_last_component);
303                 }
304                 goto err;
305         }
306
307         /* Start with the full orig_path as given by the caller. */
308         if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) {
309                 DEBUG(0, ("talloc_strdup failed\n"));
310                 status = NT_STATUS_NO_MEMORY;
311                 goto err;
312         }
313
314         /*
315          * Large directory fix normalization. If we're case sensitive, and
316          * the case preserving parameters are set to "no", normalize the case of
317          * the incoming filename from the client WHETHER IT EXISTS OR NOT !
318          * This is in conflict with the current (3.0.20) man page, but is
319          * what people expect from the "large directory howto". I'll update
320          * the man page. Thanks to jht@samba.org for finding this. JRA.
321          */
322
323         if (conn->case_sensitive && !conn->case_preserve &&
324                         !conn->short_case_preserve) {
325                 if (!strnorm(smb_fname->base_name, lp_default_case(SNUM(conn)))) {
326                         DEBUG(0, ("strnorm %s failed\n", smb_fname->base_name));
327                         status = NT_STATUS_INVALID_PARAMETER;
328                         goto err;
329                 }
330         }
331
332         /*
333          * Ensure saved_last_component is valid even if file exists.
334          */
335
336         if(save_last_component) {
337                 end = strrchr_m(smb_fname->base_name, '/');
338                 if (end) {
339                         smb_fname->original_lcomp = talloc_strdup(smb_fname,
340                                                                   end + 1);
341                 } else {
342                         smb_fname->original_lcomp =
343                             talloc_strdup(smb_fname, smb_fname->base_name);
344                 }
345                 if (smb_fname->original_lcomp == NULL) {
346                         status = NT_STATUS_NO_MEMORY;
347                         goto err;
348                 }
349         }
350
351         posix_pathnames = (lp_posix_pathnames() ||
352                                 (ucf_flags & UCF_POSIX_PATHNAMES));
353
354         /*
355          * Strip off the stream, and add it back when we're done with the
356          * base_name.
357          */
358         if (!posix_pathnames) {
359                 stream = strchr_m(smb_fname->base_name, ':');
360
361                 if (stream != NULL) {
362                         char *tmp = talloc_strdup(smb_fname, stream);
363                         if (tmp == NULL) {
364                                 status = NT_STATUS_NO_MEMORY;
365                                 goto err;
366                         }
367                         /*
368                          * Since this is actually pointing into
369                          * smb_fname->base_name this truncates base_name.
370                          */
371                         *stream = '\0';
372                         stream = tmp;
373                 }
374         }
375
376         start = smb_fname->base_name;
377
378         /*
379          * If we're providing case insensitive semantics or
380          * the underlying filesystem is case insensitive,
381          * then a case-normalized hit in the stat-cache is
382          * authoratitive. JRA.
383          *
384          * Note: We're only checking base_name.  The stream_name will be
385          * added and verified in build_stream_path().
386          */
387
388         if((!conn->case_sensitive || !(conn->fs_capabilities &
389                                        FILE_CASE_SENSITIVE_SEARCH)) &&
390             stat_cache_lookup(conn, posix_pathnames, &smb_fname->base_name, &dirpath, &start,
391                               &smb_fname->st)) {
392                 goto done;
393         }
394
395         /*
396          * Make sure "dirpath" is an allocated string, we use this for
397          * building the directories with talloc_asprintf and free it.
398          */
399
400         if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
401                 DEBUG(0, ("talloc_strdup failed\n"));
402                 status = NT_STATUS_NO_MEMORY;
403                 goto err;
404         }
405
406         /*
407          * If we have a wildcard we must walk the path to
408          * find where the error is, even if case sensitive
409          * is true.
410          */
411
412         name_has_wildcard = ms_has_wild(smb_fname->base_name);
413         if (name_has_wildcard && !allow_wcard_last_component) {
414                 /* Wildcard not valid anywhere. */
415                 status = NT_STATUS_OBJECT_NAME_INVALID;
416                 goto fail;
417         }
418
419         DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
420                  smb_fname->base_name, dirpath, start));
421
422         if (!name_has_wildcard) {
423                 /*
424                  * stat the name - if it exists then we can add the stream back (if
425                  * there was one) and be done!
426                  */
427
428                 if (posix_pathnames) {
429                         ret = SMB_VFS_LSTAT(conn, smb_fname);
430                 } else {
431                         ret = SMB_VFS_STAT(conn, smb_fname);
432                 }
433
434                 if (ret == 0) {
435                         status = check_for_dot_component(smb_fname);
436                         if (!NT_STATUS_IS_OK(status)) {
437                                 goto fail;
438                         }
439                         /* Add the path (not including the stream) to the cache. */
440                         stat_cache_add(orig_path, smb_fname->base_name,
441                                        conn->case_sensitive);
442                         DEBUG(5,("conversion of base_name finished %s -> %s\n",
443                                  orig_path, smb_fname->base_name));
444                         goto done;
445                 }
446
447                 /* Stat failed - ensure we don't use it. */
448                 SET_STAT_INVALID(smb_fname->st);
449
450                 if (errno == ENOENT) {
451                         /* Optimization when creating a new file - only
452                            the last component doesn't exist.
453                            NOTE : check_parent_exists() doesn't preserve errno.
454                         */
455                         int saved_errno = errno;
456                         status = check_parent_exists(ctx,
457                                                 conn,
458                                                 posix_pathnames,
459                                                 smb_fname,
460                                                 &dirpath,
461                                                 &start);
462                         errno = saved_errno;
463                         if (!NT_STATUS_IS_OK(status)) {
464                                 goto fail;
465                         }
466                 }
467
468                 /*
469                  * A special case - if we don't have any wildcards or mangling chars and are case
470                  * sensitive or the underlying filesystem is case insensitive then searching
471                  * won't help.
472                  */
473
474                 if ((conn->case_sensitive || !(conn->fs_capabilities &
475                                         FILE_CASE_SENSITIVE_SEARCH)) &&
476                                 !mangle_is_mangled(smb_fname->base_name, conn->params)) {
477
478                         status = check_for_dot_component(smb_fname);
479                         if (!NT_STATUS_IS_OK(status)) {
480                                 goto fail;
481                         }
482
483                         /*
484                          * The stat failed. Could be ok as it could be
485                          * a new file.
486                          */
487
488                         if (errno == ENOTDIR || errno == ELOOP) {
489                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
490                                 goto fail;
491                         } else if (errno == ENOENT) {
492                                 /*
493                                  * Was it a missing last component ?
494                                  * or a missing intermediate component ?
495                                  */
496                                 struct smb_filename parent_fname;
497                                 const char *last_component = NULL;
498
499                                 ZERO_STRUCT(parent_fname);
500                                 if (!parent_dirname(ctx, smb_fname->base_name,
501                                                         &parent_fname.base_name,
502                                                         &last_component)) {
503                                         status = NT_STATUS_NO_MEMORY;
504                                         goto fail;
505                                 }
506                                 if (posix_pathnames) {
507                                         ret = SMB_VFS_LSTAT(conn, &parent_fname);
508                                 } else {
509                                         ret = SMB_VFS_STAT(conn, &parent_fname);
510                                 }
511                                 if (ret == -1) {
512                                         if (errno == ENOTDIR ||
513                                                         errno == ENOENT ||
514                                                         errno == ELOOP) {
515                                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
516                                                 goto fail;
517                                         }
518                                 }
519
520                                 /*
521                                  * Missing last component is ok - new file.
522                                  * Also deal with permission denied elsewhere.
523                                  * Just drop out to done.
524                                  */
525                                 goto done;
526                         }
527                 }
528         } else {
529                 /*
530                  * We have a wildcard in the pathname.
531                  *
532                  * Optimization for common case where the wildcard
533                  * is in the last component and the client already
534                  * sent the correct case.
535                  * NOTE : check_parent_exists() doesn't preserve errno.
536                  */
537                 int saved_errno = errno;
538                 status = check_parent_exists(ctx,
539                                         conn,
540                                         posix_pathnames,
541                                         smb_fname,
542                                         &dirpath,
543                                         &start);
544                 errno = saved_errno;
545                 if (!NT_STATUS_IS_OK(status)) {
546                         goto fail;
547                 }
548         }
549
550         /*
551          * is_mangled() was changed to look at an entire pathname, not
552          * just a component. JRA.
553          */
554
555         if (mangle_is_mangled(start, conn->params)) {
556                 component_was_mangled = True;
557         }
558
559         /*
560          * Now we need to recursively match the name against the real
561          * directory structure.
562          */
563
564         /*
565          * Match each part of the path name separately, trying the names
566          * as is first, then trying to scan the directory for matching names.
567          */
568
569         for (; start ; start = (end?end+1:(char *)NULL)) {
570                 /*
571                  * Pinpoint the end of this section of the filename.
572                  */
573                 /* mb safe. '/' can't be in any encoded char. */
574                 end = strchr(start, '/');
575
576                 /*
577                  * Chop the name at this point.
578                  */
579                 if (end) {
580                         *end = 0;
581                 }
582
583                 if (save_last_component) {
584                         TALLOC_FREE(smb_fname->original_lcomp);
585                         smb_fname->original_lcomp = talloc_strdup(smb_fname,
586                                                         end ? end + 1 : start);
587                         if (!smb_fname->original_lcomp) {
588                                 DEBUG(0, ("talloc failed\n"));
589                                 status = NT_STATUS_NO_MEMORY;
590                                 goto err;
591                         }
592                 }
593
594                 /* The name cannot have a component of "." */
595
596                 if (ISDOT(start)) {
597                         if (!end)  {
598                                 /* Error code at the end of a pathname. */
599                                 status = NT_STATUS_OBJECT_NAME_INVALID;
600                         } else {
601                                 status = determine_path_error(end+1,
602                                                 allow_wcard_last_component);
603                         }
604                         goto fail;
605                 }
606
607                 /* The name cannot have a wildcard if it's not
608                    the last component. */
609
610                 name_has_wildcard = ms_has_wild(start);
611
612                 /* Wildcards never valid within a pathname. */
613                 if (name_has_wildcard && end) {
614                         status = NT_STATUS_OBJECT_NAME_INVALID;
615                         goto fail;
616                 }
617
618                 /* Skip the stat call if it's a wildcard end. */
619                 if (name_has_wildcard) {
620                         DEBUG(5,("Wildcard %s\n",start));
621                         goto done;
622                 }
623
624                 /*
625                  * Check if the name exists up to this point.
626                  */
627
628                 if (posix_pathnames) {
629                         ret = SMB_VFS_LSTAT(conn, smb_fname);
630                 } else {
631                         ret = SMB_VFS_STAT(conn, smb_fname);
632                 }
633
634                 if (ret == 0) {
635                         /*
636                          * It exists. it must either be a directory or this must
637                          * be the last part of the path for it to be OK.
638                          */
639                         if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) {
640                                 /*
641                                  * An intermediate part of the name isn't
642                                  * a directory.
643                                  */
644                                 DEBUG(5,("Not a dir %s\n",start));
645                                 *end = '/';
646                                 /*
647                                  * We need to return the fact that the
648                                  * intermediate name resolution failed. This
649                                  * is used to return an error of ERRbadpath
650                                  * rather than ERRbadfile. Some Windows
651                                  * applications depend on the difference between
652                                  * these two errors.
653                                  */
654                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
655                                 goto fail;
656                         }
657
658                 } else {
659                         char *found_name = NULL;
660
661                         /* Stat failed - ensure we don't use it. */
662                         SET_STAT_INVALID(smb_fname->st);
663
664                         /*
665                          * Reset errno so we can detect
666                          * directory open errors.
667                          */
668                         errno = 0;
669
670                         /*
671                          * Try to find this part of the path in the directory.
672                          */
673
674                         if (name_has_wildcard ||
675                             (get_real_filename(conn, dirpath, start,
676                                                talloc_tos(),
677                                                &found_name) == -1)) {
678                                 char *unmangled;
679
680                                 if (end) {
681                                         /*
682                                          * An intermediate part of the name
683                                          * can't be found.
684                                          */
685                                         DEBUG(5,("Intermediate not found %s\n",
686                                                         start));
687                                         *end = '/';
688
689                                         /*
690                                          * We need to return the fact that the
691                                          * intermediate name resolution failed.
692                                          * This is used to return an error of
693                                          * ERRbadpath rather than ERRbadfile.
694                                          * Some Windows applications depend on
695                                          * the difference between these two
696                                          * errors.
697                                          */
698
699                                         /*
700                                          * ENOENT, ENOTDIR and ELOOP all map
701                                          * to NT_STATUS_OBJECT_PATH_NOT_FOUND
702                                          * in the filename walk.
703                                          */
704
705                                         if (errno == ENOENT ||
706                                                         errno == ENOTDIR ||
707                                                         errno == ELOOP) {
708                                                 status =
709                                                 NT_STATUS_OBJECT_PATH_NOT_FOUND;
710                                         }
711                                         else {
712                                                 status =
713                                                 map_nt_error_from_unix(errno);
714                                         }
715                                         goto fail;
716                                 }
717
718                                 /*
719                                  * ENOENT/EACCESS are the only valid errors
720                                  * here.
721                                  */
722
723                                 if (errno == EACCES) {
724                                         if ((ucf_flags & UCF_PREP_CREATEFILE) == 0) {
725                                                 status = NT_STATUS_ACCESS_DENIED;
726                                                 goto fail;
727                                         } else {
728                                                 /*
729                                                  * This is the dropbox
730                                                  * behaviour. A dropbox is a
731                                                  * directory with only -wx
732                                                  * permissions, so
733                                                  * get_real_filename fails
734                                                  * with EACCESS, it needs to
735                                                  * list the directory. We
736                                                  * nevertheless want to allow
737                                                  * users creating a file.
738                                                  */
739                                                 errno = 0;
740                                         }
741                                 }
742
743                                 if ((errno != 0) && (errno != ENOENT)) {
744                                         /*
745                                          * ENOTDIR and ELOOP both map to
746                                          * NT_STATUS_OBJECT_PATH_NOT_FOUND
747                                          * in the filename walk.
748                                          */
749                                         if (errno == ENOTDIR ||
750                                                         errno == ELOOP) {
751                                                 status =
752                                                 NT_STATUS_OBJECT_PATH_NOT_FOUND;
753                                         } else {
754                                                 status =
755                                                 map_nt_error_from_unix(errno);
756                                         }
757                                         goto fail;
758                                 }
759
760                                 /*
761                                  * Just the last part of the name doesn't exist.
762                                  * We need to strupper() or strlower() it as
763                                  * this conversion may be used for file creation
764                                  * purposes. Fix inspired by
765                                  * Thomas Neumann <t.neumann@iku-ag.de>.
766                                  */
767                                 if (!conn->case_preserve ||
768                                     (mangle_is_8_3(start, False,
769                                                    conn->params) &&
770                                                  !conn->short_case_preserve)) {
771                                         if (!strnorm(start,
772                                                         lp_default_case(SNUM(conn)))) {
773                                                 DEBUG(0, ("strnorm %s failed\n",
774                                                         start));
775                                                 status = NT_STATUS_INVALID_PARAMETER;
776                                                 goto err;
777                                         }
778                                 }
779
780                                 /*
781                                  * check on the mangled stack to see if we can
782                                  * recover the base of the filename.
783                                  */
784
785                                 if (mangle_is_mangled(start, conn->params)
786                                     && mangle_lookup_name_from_8_3(ctx,
787                                                         start,
788                                                         &unmangled,
789                                                         conn->params)) {
790                                         char *tmp;
791                                         size_t start_ofs =
792                                             start - smb_fname->base_name;
793
794                                         if (*dirpath != '\0') {
795                                                 tmp = talloc_asprintf(
796                                                         smb_fname, "%s/%s",
797                                                         dirpath, unmangled);
798                                                 TALLOC_FREE(unmangled);
799                                         }
800                                         else {
801                                                 tmp = unmangled;
802                                         }
803                                         if (tmp == NULL) {
804                                                 DEBUG(0, ("talloc failed\n"));
805                                                 status = NT_STATUS_NO_MEMORY;
806                                                 goto err;
807                                         }
808                                         TALLOC_FREE(smb_fname->base_name);
809                                         smb_fname->base_name = tmp;
810                                         start =
811                                             smb_fname->base_name + start_ofs;
812                                         end = start + strlen(start);
813                                 }
814
815                                 DEBUG(5,("New file %s\n",start));
816                                 goto done;
817                         }
818
819
820                         /*
821                          * Restore the rest of the string. If the string was
822                          * mangled the size may have changed.
823                          */
824                         if (end) {
825                                 char *tmp;
826                                 size_t start_ofs =
827                                     start - smb_fname->base_name;
828
829                                 if (*dirpath != '\0') {
830                                         tmp = talloc_asprintf(smb_fname,
831                                                 "%s/%s/%s", dirpath,
832                                                 found_name, end+1);
833                                 }
834                                 else {
835                                         tmp = talloc_asprintf(smb_fname,
836                                                 "%s/%s", found_name,
837                                                 end+1);
838                                 }
839                                 if (tmp == NULL) {
840                                         DEBUG(0, ("talloc_asprintf failed\n"));
841                                         status = NT_STATUS_NO_MEMORY;
842                                         goto err;
843                                 }
844                                 TALLOC_FREE(smb_fname->base_name);
845                                 smb_fname->base_name = tmp;
846                                 start = smb_fname->base_name + start_ofs;
847                                 end = start + strlen(found_name);
848                                 *end = '\0';
849                         } else {
850                                 char *tmp;
851                                 size_t start_ofs =
852                                     start - smb_fname->base_name;
853
854                                 if (*dirpath != '\0') {
855                                         tmp = talloc_asprintf(smb_fname,
856                                                 "%s/%s", dirpath,
857                                                 found_name);
858                                 } else {
859                                         tmp = talloc_strdup(smb_fname,
860                                                 found_name);
861                                 }
862                                 if (tmp == NULL) {
863                                         DEBUG(0, ("talloc failed\n"));
864                                         status = NT_STATUS_NO_MEMORY;
865                                         goto err;
866                                 }
867                                 TALLOC_FREE(smb_fname->base_name);
868                                 smb_fname->base_name = tmp;
869                                 start = smb_fname->base_name + start_ofs;
870
871                                 /*
872                                  * We just scanned for, and found the end of
873                                  * the path. We must return a valid stat struct
874                                  * if it exists. JRA.
875                                  */
876
877                                 if (posix_pathnames) {
878                                         ret = SMB_VFS_LSTAT(conn, smb_fname);
879                                 } else {
880                                         ret = SMB_VFS_STAT(conn, smb_fname);
881                                 }
882
883                                 if (ret != 0) {
884                                         SET_STAT_INVALID(smb_fname->st);
885                                 }
886                         }
887
888                         TALLOC_FREE(found_name);
889                 } /* end else */
890
891 #ifdef DEVELOPER
892                 /*
893                  * This sucks!
894                  * We should never provide different behaviors
895                  * depending on DEVELOPER!!!
896                  */
897                 if (VALID_STAT(smb_fname->st)) {
898                         bool delete_pending;
899                         uint32_t name_hash;
900
901                         status = file_name_hash(conn,
902                                         smb_fname_str_dbg(smb_fname),
903                                         &name_hash);
904                         if (!NT_STATUS_IS_OK(status)) {
905                                 goto fail;
906                         }
907
908                         get_file_infos(vfs_file_id_from_sbuf(conn,
909                                                              &smb_fname->st),
910                                        name_hash,
911                                        &delete_pending, NULL);
912                         if (delete_pending) {
913                                 status = NT_STATUS_DELETE_PENDING;
914                                 goto fail;
915                         }
916                 }
917 #endif
918
919                 /*
920                  * Add to the dirpath that we have resolved so far.
921                  */
922
923                 if (*dirpath != '\0') {
924                         char *tmp = talloc_asprintf(ctx,
925                                         "%s/%s", dirpath, start);
926                         if (!tmp) {
927                                 DEBUG(0, ("talloc_asprintf failed\n"));
928                                 status = NT_STATUS_NO_MEMORY;
929                                 goto err;
930                         }
931                         TALLOC_FREE(dirpath);
932                         dirpath = tmp;
933                 }
934                 else {
935                         TALLOC_FREE(dirpath);
936                         if (!(dirpath = talloc_strdup(ctx,start))) {
937                                 DEBUG(0, ("talloc_strdup failed\n"));
938                                 status = NT_STATUS_NO_MEMORY;
939                                 goto err;
940                         }
941                 }
942
943                 /*
944                  * Cache the dirpath thus far. Don't cache a name with mangled
945                  * or wildcard components as this can change the size.
946                  */
947                 if(!component_was_mangled && !name_has_wildcard) {
948                         stat_cache_add(orig_path, dirpath,
949                                         conn->case_sensitive);
950                 }
951
952                 /*
953                  * Restore the / that we wiped out earlier.
954                  */
955                 if (end) {
956                         *end = '/';
957                 }
958         }
959
960         /*
961          * Cache the full path. Don't cache a name with mangled or wildcard
962          * components as this can change the size.
963          */
964
965         if(!component_was_mangled && !name_has_wildcard) {
966                 stat_cache_add(orig_path, smb_fname->base_name,
967                                conn->case_sensitive);
968         }
969
970         /*
971          * The name has been resolved.
972          */
973
974         DEBUG(5,("conversion finished %s -> %s\n", orig_path,
975                  smb_fname->base_name));
976
977  done:
978         /* Add back the stream if one was stripped off originally. */
979         if (stream != NULL) {
980                 smb_fname->stream_name = stream;
981
982                 /* Check path now that the base_name has been converted. */
983                 status = build_stream_path(ctx, conn, smb_fname);
984                 if (!NT_STATUS_IS_OK(status)) {
985                         goto fail;
986                 }
987         }
988         TALLOC_FREE(dirpath);
989         *smb_fname_out = smb_fname;
990         return NT_STATUS_OK;
991  fail:
992         DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
993         if (*dirpath != '\0') {
994                 smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s",
995                                                        dirpath, start);
996         } else {
997                 smb_fname->base_name = talloc_strdup(smb_fname, start);
998         }
999         if (!smb_fname->base_name) {
1000                 DEBUG(0, ("talloc_asprintf failed\n"));
1001                 status = NT_STATUS_NO_MEMORY;
1002                 goto err;
1003         }
1004
1005         *smb_fname_out = smb_fname;
1006         TALLOC_FREE(dirpath);
1007         return status;
1008  err:
1009         TALLOC_FREE(smb_fname);
1010         return status;
1011 }
1012
1013 /****************************************************************************
1014  Ensure a path is not vetoed.
1015 ****************************************************************************/
1016
1017 static NTSTATUS check_veto_path(connection_struct *conn, const char *name)
1018 {
1019         if (IS_VETO_PATH(conn, name))  {
1020                 /* Is it not dot or dot dot. */
1021                 if (!(ISDOT(name) || ISDOTDOT(name))) {
1022                         DEBUG(5,("check_veto_path: file path name %s vetoed\n",
1023                                                 name));
1024                         return map_nt_error_from_unix(ENOENT);
1025                 }
1026         }
1027         return NT_STATUS_OK;
1028 }
1029
1030 /****************************************************************************
1031  Check a filename - possibly calling check_reduced_name.
1032  This is called by every routine before it allows an operation on a filename.
1033  It does any final confirmation necessary to ensure that the filename is
1034  a valid one for the user to access.
1035 ****************************************************************************/
1036
1037 NTSTATUS check_name(connection_struct *conn, const char *name)
1038 {
1039         NTSTATUS status = check_veto_path(conn, name);
1040
1041         if (!NT_STATUS_IS_OK(status)) {
1042                 return status;
1043         }
1044
1045         if (!lp_widelinks(SNUM(conn)) || !lp_follow_symlinks(SNUM(conn))) {
1046                 status = check_reduced_name(conn,name);
1047                 if (!NT_STATUS_IS_OK(status)) {
1048                         DEBUG(5,("check_name: name %s failed with %s\n",name,
1049                                                 nt_errstr(status)));
1050                         return status;
1051                 }
1052         }
1053
1054         return NT_STATUS_OK;
1055 }
1056
1057 /****************************************************************************
1058  Must be called as root. Creates the struct privilege_paths
1059  attached to the struct smb_request if this call is successful.
1060 ****************************************************************************/
1061
1062 static NTSTATUS check_name_with_privilege(connection_struct *conn,
1063                 struct smb_request *smbreq,
1064                 const char *name)
1065 {
1066         NTSTATUS status = check_veto_path(conn, name);
1067
1068         if (!NT_STATUS_IS_OK(status)) {
1069                 return status;
1070         }
1071         return check_reduced_name_with_privilege(conn,
1072                         name,
1073                         smbreq);
1074 }
1075
1076 /****************************************************************************
1077  Check if two filenames are equal.
1078  This needs to be careful about whether we are case sensitive.
1079 ****************************************************************************/
1080
1081 static bool fname_equal(const char *name1, const char *name2,
1082                 bool case_sensitive)
1083 {
1084         /* Normal filename handling */
1085         if (case_sensitive) {
1086                 return(strcmp(name1,name2) == 0);
1087         }
1088
1089         return(strequal(name1,name2));
1090 }
1091
1092 /****************************************************************************
1093  Scan a directory to find a filename, matching without case sensitivity.
1094  If the name looks like a mangled name then try via the mangling functions
1095 ****************************************************************************/
1096
1097 static int get_real_filename_full_scan(connection_struct *conn,
1098                                        const char *path, const char *name,
1099                                        bool mangled,
1100                                        TALLOC_CTX *mem_ctx, char **found_name)
1101 {
1102         struct smb_Dir *cur_dir;
1103         const char *dname = NULL;
1104         char *talloced = NULL;
1105         char *unmangled_name = NULL;
1106         long curpos;
1107
1108         /* handle null paths */
1109         if ((path == NULL) || (*path == 0)) {
1110                 path = ".";
1111         }
1112
1113         /* If we have a case-sensitive filesystem, it doesn't do us any
1114          * good to search for a name. If a case variation of the name was
1115          * there, then the original stat(2) would have found it.
1116          */
1117         if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) {
1118                 errno = ENOENT;
1119                 return -1;
1120         }
1121
1122         /*
1123          * The incoming name can be mangled, and if we de-mangle it
1124          * here it will not compare correctly against the filename (name2)
1125          * read from the directory and then mangled by the name_to_8_3()
1126          * call. We need to mangle both names or neither.
1127          * (JRA).
1128          *
1129          * Fix for bug found by Dina Fine. If in case sensitive mode then
1130          * the mangle cache is no good (3 letter extension could be wrong
1131          * case - so don't demangle in this case - leave as mangled and
1132          * allow the mangling of the directory entry read (which is done
1133          * case insensitively) to match instead. This will lead to more
1134          * false positive matches but we fail completely without it. JRA.
1135          */
1136
1137         if (mangled && !conn->case_sensitive) {
1138                 mangled = !mangle_lookup_name_from_8_3(talloc_tos(), name,
1139                                                        &unmangled_name,
1140                                                        conn->params);
1141                 if (!mangled) {
1142                         /* Name is now unmangled. */
1143                         name = unmangled_name;
1144                 }
1145         }
1146
1147         /* open the directory */
1148         if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) {
1149                 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
1150                 TALLOC_FREE(unmangled_name);
1151                 return -1;
1152         }
1153
1154         /* now scan for matching names */
1155         curpos = 0;
1156         while ((dname = ReadDirName(cur_dir, &curpos, NULL, &talloced))) {
1157
1158                 /* Is it dot or dot dot. */
1159                 if (ISDOT(dname) || ISDOTDOT(dname)) {
1160                         TALLOC_FREE(talloced);
1161                         continue;
1162                 }
1163
1164                 /*
1165                  * At this point dname is the unmangled name.
1166                  * name is either mangled or not, depending on the state
1167                  * of the "mangled" variable. JRA.
1168                  */
1169
1170                 /*
1171                  * Check mangled name against mangled name, or unmangled name
1172                  * against unmangled name.
1173                  */
1174
1175                 if ((mangled && mangled_equal(name,dname,conn->params)) ||
1176                         fname_equal(name, dname, conn->case_sensitive)) {
1177                         /* we've found the file, change it's name and return */
1178                         *found_name = talloc_strdup(mem_ctx, dname);
1179                         TALLOC_FREE(unmangled_name);
1180                         TALLOC_FREE(cur_dir);
1181                         if (!*found_name) {
1182                                 errno = ENOMEM;
1183                                 TALLOC_FREE(talloced);
1184                                 return -1;
1185                         }
1186                         TALLOC_FREE(talloced);
1187                         return 0;
1188                 }
1189                 TALLOC_FREE(talloced);
1190         }
1191
1192         TALLOC_FREE(unmangled_name);
1193         TALLOC_FREE(cur_dir);
1194         errno = ENOENT;
1195         return -1;
1196 }
1197
1198 /****************************************************************************
1199  Wrapper around the vfs get_real_filename and the full directory scan
1200  fallback.
1201 ****************************************************************************/
1202
1203 int get_real_filename(connection_struct *conn, const char *path,
1204                       const char *name, TALLOC_CTX *mem_ctx,
1205                       char **found_name)
1206 {
1207         int ret;
1208         bool mangled;
1209
1210         mangled = mangle_is_mangled(name, conn->params);
1211
1212         if (mangled) {
1213                 return get_real_filename_full_scan(conn, path, name, mangled,
1214                                                    mem_ctx, found_name);
1215         }
1216
1217         /* Try the vfs first to take advantage of case-insensitive stat. */
1218         ret = SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name);
1219
1220         /*
1221          * If the case-insensitive stat was successful, or returned an error
1222          * other than EOPNOTSUPP then there is no need to fall back on the
1223          * full directory scan.
1224          */
1225         if (ret == 0 || (ret == -1 && errno != EOPNOTSUPP)) {
1226                 return ret;
1227         }
1228
1229         return get_real_filename_full_scan(conn, path, name, mangled, mem_ctx,
1230                                            found_name);
1231 }
1232
1233 static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
1234                                   connection_struct *conn,
1235                                   struct smb_filename *smb_fname)
1236 {
1237         NTSTATUS status;
1238         unsigned int i, num_streams = 0;
1239         struct stream_struct *streams = NULL;
1240
1241         if (SMB_VFS_STAT(conn, smb_fname) == 0) {
1242                 DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
1243                 return NT_STATUS_OK;
1244         }
1245
1246         if (errno != ENOENT) {
1247                 DEBUG(10, ("vfs_stat failed: %s\n", strerror(errno)));
1248                 status = map_nt_error_from_unix(errno);
1249                 goto fail;
1250         }
1251
1252         /* Fall back to a case-insensitive scan of all streams on the file. */
1253         status = vfs_streaminfo(conn, NULL, smb_fname->base_name, mem_ctx,
1254                                 &num_streams, &streams);
1255
1256         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1257                 SET_STAT_INVALID(smb_fname->st);
1258                 return NT_STATUS_OK;
1259         }
1260
1261         if (!NT_STATUS_IS_OK(status)) {
1262                 DEBUG(10, ("vfs_streaminfo failed: %s\n", nt_errstr(status)));
1263                 goto fail;
1264         }
1265
1266         for (i=0; i<num_streams; i++) {
1267                 DEBUG(10, ("comparing [%s] and [%s]: ",
1268                            smb_fname->stream_name, streams[i].name));
1269                 if (fname_equal(smb_fname->stream_name, streams[i].name,
1270                                 conn->case_sensitive)) {
1271                         DEBUGADD(10, ("equal\n"));
1272                         break;
1273                 }
1274                 DEBUGADD(10, ("not equal\n"));
1275         }
1276
1277         /* Couldn't find the stream. */
1278         if (i == num_streams) {
1279                 SET_STAT_INVALID(smb_fname->st);
1280                 TALLOC_FREE(streams);
1281                 return NT_STATUS_OK;
1282         }
1283
1284         DEBUG(10, ("case insensitive stream. requested: %s, actual: %s\n",
1285                 smb_fname->stream_name, streams[i].name));
1286
1287
1288         TALLOC_FREE(smb_fname->stream_name);
1289         smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name);
1290         if (smb_fname->stream_name == NULL) {
1291                 status = NT_STATUS_NO_MEMORY;
1292                 goto fail;
1293         }
1294
1295         SET_STAT_INVALID(smb_fname->st);
1296
1297         if (SMB_VFS_STAT(conn, smb_fname) == 0) {
1298                 DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
1299         }
1300         status = NT_STATUS_OK;
1301  fail:
1302         TALLOC_FREE(streams);
1303         return status;
1304 }
1305
1306 /**
1307  * Go through all the steps to validate a filename.
1308  *
1309  * @param ctx           talloc_ctx to allocate memory with.
1310  * @param conn          connection struct for vfs calls.
1311  * @param dfs_path      Whether this path requires dfs resolution.
1312  * @param smbreq        SMB request if we're using privileges.
1313  * @param name_in       The unconverted name.
1314  * @param ucf_flags     flags to pass through to unix_convert().
1315  *                      UCF_ALWAYS_ALLOW_WCARD_LCOMP will be OR'd in if
1316  *                      p_cont_wcard != NULL and is true and
1317  *                      UCF_COND_ALLOW_WCARD_LCOMP.
1318  * @param p_cont_wcard  If not NULL, will be set to true if the dfs path
1319  *                      resolution detects a wildcard.
1320  * @param pp_smb_fname  The final converted name will be allocated if the
1321  *                      return is NT_STATUS_OK.
1322  *
1323  * @return NT_STATUS_OK if all operations completed succesfully, appropriate
1324  *         error otherwise.
1325  */
1326 static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx,
1327                                 connection_struct *conn,
1328                                 bool dfs_path,
1329                                 struct smb_request *smbreq,
1330                                 const char *name_in,
1331                                 uint32_t ucf_flags,
1332                                 bool *ppath_contains_wcard,
1333                                 struct smb_filename **pp_smb_fname)
1334 {
1335         NTSTATUS status;
1336         bool allow_wcards = (ucf_flags & (UCF_COND_ALLOW_WCARD_LCOMP|UCF_ALWAYS_ALLOW_WCARD_LCOMP));
1337         char *fname = NULL;
1338
1339         *pp_smb_fname = NULL;
1340
1341         status = resolve_dfspath_wcard(ctx, conn,
1342                                 dfs_path,
1343                                 name_in,
1344                                 allow_wcards,
1345                                 !conn->sconn->using_smb2,
1346                                 &fname,
1347                                 ppath_contains_wcard);
1348         if (!NT_STATUS_IS_OK(status)) {
1349                 DEBUG(10,("filename_convert_internal: resolve_dfspath failed "
1350                         "for name %s with %s\n",
1351                         name_in,
1352                         nt_errstr(status) ));
1353                 return status;
1354         }
1355
1356         if (is_fake_file_path(name_in)) {
1357                 SMB_STRUCT_STAT st;
1358                 ZERO_STRUCT(st);
1359                 st.st_ex_nlink = 1;
1360                 *pp_smb_fname = synthetic_smb_fname_split(ctx,
1361                                                           name_in,
1362                                                           &st);
1363                 if (*pp_smb_fname == NULL) {
1364                         return NT_STATUS_NO_MEMORY;
1365                 }
1366                 return NT_STATUS_OK;
1367         }
1368
1369         /*
1370          * If the caller conditionally allows wildcard lookups, only add the
1371          * always allow if the path actually does contain a wildcard.
1372          */
1373         if (ucf_flags & UCF_COND_ALLOW_WCARD_LCOMP &&
1374             ppath_contains_wcard != NULL && *ppath_contains_wcard) {
1375                 ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
1376         }
1377
1378         status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags);
1379         if (!NT_STATUS_IS_OK(status)) {
1380                 DEBUG(10,("filename_convert_internal: unix_convert failed "
1381                         "for name %s with %s\n",
1382                         fname,
1383                         nt_errstr(status) ));
1384                 return status;
1385         }
1386
1387         if ((ucf_flags & UCF_UNIX_NAME_LOOKUP) &&
1388                         VALID_STAT((*pp_smb_fname)->st) &&
1389                         S_ISLNK((*pp_smb_fname)->st.st_ex_mode)) {
1390                 return check_veto_path(conn, (*pp_smb_fname)->base_name);
1391         }
1392
1393         if (!smbreq) {
1394                 status = check_name(conn, (*pp_smb_fname)->base_name);
1395         } else {
1396                 status = check_name_with_privilege(conn, smbreq, (*pp_smb_fname)->base_name);
1397         }
1398         if (!NT_STATUS_IS_OK(status)) {
1399                 DEBUG(3,("filename_convert_internal: check_name failed "
1400                         "for name %s with %s\n",
1401                         smb_fname_str_dbg(*pp_smb_fname),
1402                         nt_errstr(status) ));
1403                 TALLOC_FREE(*pp_smb_fname);
1404                 return status;
1405         }
1406
1407         return status;
1408 }
1409
1410 /*
1411  * Go through all the steps to validate a filename.
1412  * Non-root version.
1413  */
1414
1415 NTSTATUS filename_convert(TALLOC_CTX *ctx,
1416                                 connection_struct *conn,
1417                                 bool dfs_path,
1418                                 const char *name_in,
1419                                 uint32_t ucf_flags,
1420                                 bool *ppath_contains_wcard,
1421                                 struct smb_filename **pp_smb_fname)
1422 {
1423         return filename_convert_internal(ctx,
1424                                         conn,
1425                                         dfs_path,
1426                                         NULL,
1427                                         name_in,
1428                                         ucf_flags,
1429                                         ppath_contains_wcard,
1430                                         pp_smb_fname);
1431 }
1432
1433 /*
1434  * Go through all the steps to validate a filename.
1435  * root (privileged) version.
1436  */
1437
1438 NTSTATUS filename_convert_with_privilege(TALLOC_CTX *ctx,
1439                                 connection_struct *conn,
1440                                 struct smb_request *smbreq,
1441                                 const char *name_in,
1442                                 uint32_t ucf_flags,
1443                                 bool *ppath_contains_wcard,
1444                                 struct smb_filename **pp_smb_fname)
1445 {
1446         return filename_convert_internal(ctx,
1447                                         conn,
1448                                         smbreq->flags2 & FLAGS2_DFS_PATHNAMES,
1449                                         smbreq,
1450                                         name_in,
1451                                         ucf_flags,
1452                                         ppath_contains_wcard,
1453                                         pp_smb_fname);
1454 }