r24595: Fix Coverity ID 393
[metze/samba/wip.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-2004
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
29 static BOOL scan_directory(connection_struct *conn, const char *path,
30                            char *name, char **found_name);
31
32 /****************************************************************************
33  Mangle the 2nd name and check if it is then equal to the first name.
34 ****************************************************************************/
35
36 static BOOL mangled_equal(const char *name1, const char *name2,
37                           const struct share_params *p)
38 {
39         pstring tmpname;
40         
41         pstrcpy(tmpname, name2);
42         mangle_map(tmpname, True, False, p);
43         return strequal(name1, tmpname);
44 }
45
46 /****************************************************************************
47  Cope with the differing wildcard and non-wildcard error cases.
48 ****************************************************************************/
49
50 static NTSTATUS determine_path_error(const char *name, BOOL allow_wcard_last_component)
51 {
52         const char *p;
53
54         if (!allow_wcard_last_component) {
55                 /* Error code within a pathname. */
56                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
57         }
58
59         /* We're terminating here so we
60          * can be a little slower and get
61          * the error code right. Windows
62          * treats the last part of the pathname
63          * separately I think, so if the last
64          * component is a wildcard then we treat
65          * this ./ as "end of component" */
66
67         p = strchr(name, '/');
68
69         if (!p && (ms_has_wild(name) || ISDOT(name))) {
70                 /* Error code at the end of a pathname. */
71                 return NT_STATUS_OBJECT_NAME_INVALID;
72         } else {
73                 /* Error code within a pathname. */
74                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
75         }
76 }
77         
78 /****************************************************************************
79 This routine is called to convert names from the dos namespace to unix
80 namespace. It needs to handle any case conversions, mangling, format
81 changes etc.
82
83 We assume that we have already done a chdir() to the right "root" directory
84 for this service.
85
86 The function will return an NTSTATUS error if some part of the name except for the last
87 part cannot be resolved, else NT_STATUS_OK.
88
89 Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we didn't
90 get any fatal errors that should immediately terminate the calling
91 SMB processing whilst resolving.
92
93 If the saved_last_component != 0, then the unmodified last component
94 of the pathname is returned there. This is used in an exceptional
95 case in reply_mv (so far). If saved_last_component == 0 then nothing
96 is returned there.
97
98 If last_component_wcard is true then a MS wildcard was detected and
99 should be allowed in the last component of the path only.
100
101 On exit from unix_convert, if *pst was not null, then the file stat
102 struct will be returned if the file exists and was found, if not this
103 stat struct will be filled with zeros (and this can be detected by checking
104 for nlinks = 0, which can never be true for any file).
105 ****************************************************************************/
106
107 NTSTATUS unix_convert(connection_struct *conn,
108                         pstring orig_path,
109                         BOOL allow_wcard_last_component,
110                         char *saved_last_component,
111                         SMB_STRUCT_STAT *pst)
112 {
113         SMB_STRUCT_STAT st;
114         char *start, *end;
115         char *dirpath = NULL;
116         char *name = NULL;
117         BOOL component_was_mangled = False;
118         BOOL name_has_wildcard = False;
119         NTSTATUS result;
120
121         SET_STAT_INVALID(*pst);
122
123         if(saved_last_component) {
124                 *saved_last_component = 0;
125         }
126
127         if (conn->printer) {
128                 /* we don't ever use the filenames on a printer share as a
129                         filename - so don't convert them */
130                 return NT_STATUS_OK;
131         }
132
133         DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
134
135         /*
136          * Conversion to basic unix format is already done in check_path_syntax().
137          */
138
139         /*
140          * Names must be relative to the root of the service - any leading /.
141          * and trailing /'s should have been trimmed by check_path_syntax().
142          */
143
144 #ifdef DEVELOPER
145         SMB_ASSERT(*orig_path != '/');
146 #endif
147
148         /*
149          * If we trimmed down to a single '\0' character
150          * then we should use the "." directory to avoid
151          * searching the cache, but not if we are in a
152          * printing share.
153          * As we know this is valid we can return true here.
154          */
155
156         if (!*orig_path) {
157                 if (!(name = SMB_STRDUP("."))) {
158                         return NT_STATUS_NO_MEMORY;
159                 }
160                 if (SMB_VFS_STAT(conn,name,&st) == 0) {
161                         *pst = st;
162                 }
163                 DEBUG(5,("conversion finished \"\" -> %s\n",name));
164                 goto done;
165         }
166
167         if (orig_path[0] == '.' && (orig_path[1] == '/' || orig_path[1] == '\0')) {
168                 /* Start of pathname can't be "." only. */
169                 if (orig_path[1] == '\0' || orig_path[2] == '\0') {
170                         result = NT_STATUS_OBJECT_NAME_INVALID;
171                 } else {
172                         result =determine_path_error(
173                                 &orig_path[2], allow_wcard_last_component);
174                 }
175                 return result;
176         }
177
178         /*
179          * Ensure saved_last_component is valid even if file exists.
180          */
181
182         if(saved_last_component) {
183                 end = strrchr_m(orig_path, '/');
184                 if (end) {
185                         pstrcpy(saved_last_component, end + 1);
186                 } else {
187                         pstrcpy(saved_last_component, orig_path);
188                 }
189         }
190
191         if (!(name = SMB_STRDUP(orig_path))) {
192                 DEBUG(0, ("strdup failed\n"));
193                 return NT_STATUS_NO_MEMORY;
194         }
195
196         /*
197          * Large directory fix normalization. If we're case sensitive, and
198          * the case preserving parameters are set to "no", normalize the case of
199          * the incoming filename from the client WHETHER IT EXISTS OR NOT !
200          * This is in conflict with the current (3.0.20) man page, but is
201          * what people expect from the "large directory howto". I'll update
202          * the man page. Thanks to jht@samba.org for finding this. JRA.
203          */
204
205         if (conn->case_sensitive && !conn->case_preserve && !conn->short_case_preserve) {
206                 strnorm(name, lp_defaultcase(SNUM(conn)));
207         }
208
209         start = name;
210
211         if(!conn->case_sensitive
212            && stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
213                 *pst = st;
214                 goto done;
215         }
216
217         /*
218          * Make sure "dirpath" is an allocated string, we use this for
219          * building the directories with asprintf and free it.
220          */
221
222         if ((dirpath == NULL) && (!(dirpath = SMB_STRDUP("")))) {
223                 DEBUG(0, ("strdup failed\n"));
224                 SAFE_FREE(name);
225                 return NT_STATUS_NO_MEMORY;
226         }
227
228         /*
229          * stat the name - if it exists then we are all done!
230          */
231
232         if (SMB_VFS_STAT(conn,name,&st) == 0) {
233                 /* Ensure we catch all names with in "/."
234                    this is disallowed under Windows. */
235                 const char *p = strstr(name, "/."); /* mb safe. */
236                 if (p) {
237                         if (p[2] == '/') {
238                                 /* Error code within a pathname. */
239                                 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
240                                 goto fail;
241                         } else if (p[2] == '\0') {
242                                 /* Error code at the end of a pathname. */
243                                 result = NT_STATUS_OBJECT_NAME_INVALID;
244                                 goto fail;
245                         }
246                 }
247                 stat_cache_add(orig_path, name, conn->case_sensitive);
248                 DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
249                 *pst = st;
250                 goto done;
251         }
252
253         DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n", name, dirpath, start));
254
255         /*
256          * A special case - if we don't have any mangling chars and are case
257          * sensitive then searching won't help.
258          */
259
260         if (conn->case_sensitive &&
261                         !mangle_is_mangled(name, conn->params) &&
262                         !*lp_mangled_map(conn->params)) {
263                 goto done;
264         }
265
266         /*
267          * is_mangled() was changed to look at an entire pathname, not
268          * just a component. JRA.
269          */
270
271         if (mangle_is_mangled(start, conn->params)) {
272                 component_was_mangled = True;
273         }
274
275         /*
276          * Now we need to recursively match the name against the real
277          * directory structure.
278          */
279
280         /*
281          * Match each part of the path name separately, trying the names
282          * as is first, then trying to scan the directory for matching names.
283          */
284
285         for (; start ; start = (end?end+1:(char *)NULL)) {
286                 /*
287                  * Pinpoint the end of this section of the filename.
288                  */
289                 end = strchr(start, '/'); /* mb safe. '/' can't be in any encoded char. */
290
291                 /*
292                  * Chop the name at this point.
293                  */
294                 if (end) {
295                         *end = 0;
296                 }
297
298                 if (saved_last_component != 0) {
299                         pstrcpy(saved_last_component, end ? end + 1 : start);
300                 }
301
302                 /* The name cannot have a component of "." */
303
304                 if (ISDOT(start)) {
305                         if (!end)  {
306                                 /* Error code at the end of a pathname. */
307                                 result = NT_STATUS_OBJECT_NAME_INVALID;
308                         } else {
309                                 result = determine_path_error(end+1,
310                                                 allow_wcard_last_component);
311                         }
312                         goto fail;
313                 }
314
315                 /* The name cannot have a wildcard if it's not
316                    the last component. */
317
318                 name_has_wildcard = ms_has_wild(start);
319
320                 /* Wildcard not valid anywhere. */
321                 if (name_has_wildcard && !allow_wcard_last_component) {
322                         result = NT_STATUS_OBJECT_NAME_INVALID;
323                         goto fail;
324                 }
325
326                 /* Wildcards never valid within a pathname. */
327                 if (name_has_wildcard && end) {
328                         result = NT_STATUS_OBJECT_NAME_INVALID;
329                         goto fail;
330                 }
331
332                 /*
333                  * Check if the name exists up to this point.
334                  */
335
336                 if (SMB_VFS_STAT(conn,name, &st) == 0) {
337                         /*
338                          * It exists. it must either be a directory or this must be
339                          * the last part of the path for it to be OK.
340                          */
341                         if (end && !(st.st_mode & S_IFDIR)) {
342                                 /*
343                                  * An intermediate part of the name isn't a directory.
344                                  */
345                                 DEBUG(5,("Not a dir %s\n",start));
346                                 *end = '/';
347                                 /*
348                                  * We need to return the fact that the intermediate
349                                  * name resolution failed. This is used to return an
350                                  * error of ERRbadpath rather than ERRbadfile. Some
351                                  * Windows applications depend on the difference between
352                                  * these two errors.
353                                  */
354                                 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
355                                 goto fail;
356                         }
357
358                         if (!end) {
359                                 /*
360                                  * We just scanned for, and found the end of the path.
361                                  * We must return the valid stat struct.
362                                  * JRA.
363                                  */
364
365                                 *pst = st;
366                         }
367
368                 } else {
369                         char *found_name = NULL;
370
371                         /* Stat failed - ensure we don't use it. */
372                         SET_STAT_INVALID(st);
373
374                         /* Reset errno so we can detect directory open errors. */
375                         errno = 0;
376
377                         /*
378                          * Try to find this part of the path in the directory.
379                          */
380
381                         if (name_has_wildcard || 
382                             !scan_directory(conn, dirpath, start, &found_name)) {
383                                 char *unmangled;
384
385                                 if (end) {
386                                         /*
387                                          * An intermediate part of the name can't be found.
388                                          */
389                                         DEBUG(5,("Intermediate not found %s\n",start));
390                                         *end = '/';
391
392                                         /*
393                                          * We need to return the fact that the intermediate
394                                          * name resolution failed. This is used to return an
395                                          * error of ERRbadpath rather than ERRbadfile. Some
396                                          * Windows applications depend on the difference between
397                                          * these two errors.
398                                          */
399
400                                         /*
401                                          * ENOENT, ENOTDIR and ELOOP all map
402                                          * to NT_STATUS_OBJECT_PATH_NOT_FOUND
403                                          * in the filename walk.
404                                          */
405
406                                         if (errno == ENOENT ||
407                                                         errno == ENOTDIR ||
408                                                         errno == ELOOP) {
409                                                 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
410                                         }
411                                         else {
412                                                 result = map_nt_error_from_unix(errno);
413                                         }
414                                         goto fail;
415                                 }
416
417                                 /* ENOENT is the only valid error here. */
418                                 if (errno != ENOENT) {
419                                         /*
420                                          * ENOTDIR and ELOOP both map to
421                                          * NT_STATUS_OBJECT_PATH_NOT_FOUND
422                                          * in the filename walk.
423                                          */
424                                         if (errno == ENOTDIR ||
425                                                         errno == ELOOP) {
426                                                 result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
427                                         }
428                                         else {
429                                                 result = map_nt_error_from_unix(errno);
430                                         }
431                                         goto fail;
432                                 }
433
434                                 /*
435                                  * Just the last part of the name doesn't exist.
436                                  * We need to strupper() or strlower() it as
437                                  * this conversion may be used for file creation 
438                                  * purposes. Fix inspired by Thomas Neumann <t.neumann@iku-ag.de>.
439                                  */
440                                 if (!conn->case_preserve ||
441                                     (mangle_is_8_3(start, False, conn->params) &&
442                                                  !conn->short_case_preserve)) {
443                                         strnorm(start, lp_defaultcase(SNUM(conn)));
444                                 }
445
446                                 /*
447                                  * check on the mangled stack to see if we can recover the 
448                                  * base of the filename.
449                                  */
450
451                                 if (mangle_is_mangled(start, conn->params)
452                                     && mangle_check_cache_alloc(start, &unmangled,
453                                                                 conn->params)) {
454                                         char *tmp;
455                                         size_t start_ofs = start - name;
456
457                                         if (*dirpath != '\0') {
458                                                 asprintf(&tmp, "%s/%s", dirpath,
459                                                          unmangled);
460                                                 SAFE_FREE(unmangled);
461                                         }
462                                         else {
463                                                 tmp = unmangled;
464                                         }
465                                         if (tmp == NULL) {
466                                                 DEBUG(0, ("malloc failed\n"));
467                                                 result = NT_STATUS_NO_MEMORY;
468                                         }
469                                         SAFE_FREE(name);
470                                         name = tmp;
471                                         start = name + start_ofs;
472                                         end = start + strlen(start);
473                                 }
474
475                                 DEBUG(5,("New file %s\n",start));
476                                 goto done;
477                         }
478
479
480                         /*
481                          * Restore the rest of the string. If the string was mangled the size
482                          * may have changed.
483                          */
484                         if (end) {
485                                 char *tmp;
486                                 size_t start_ofs = start - name;
487
488                                 if (*dirpath != '\0') {
489                                         asprintf(&tmp, "%s/%s/%s", dirpath,
490                                                  found_name, end+1);
491                                 }
492                                 else {
493                                         asprintf(&tmp, "%s/%s", found_name,
494                                                  end+1);
495                                 }
496                                 if (tmp == NULL) {
497                                         DEBUG(0, ("asprintf failed\n"));
498                                         result = NT_STATUS_NO_MEMORY;
499                                 }
500                                 SAFE_FREE(name);
501                                 name = tmp;
502                                 start = name + start_ofs;
503                                 end = start + strlen(found_name);
504                                 *end = '\0';
505                         } else {
506                                 char *tmp;
507                                 size_t start_ofs = start - name;
508
509                                 if (*dirpath != '\0') {
510                                         asprintf(&tmp, "%s/%s", dirpath,
511                                                  found_name);
512                                 }
513                                 else {
514                                         tmp = SMB_STRDUP(found_name);
515                                 }
516                                 if (tmp == NULL) {
517                                         DEBUG(0, ("malloc failed\n"));
518                                         result = NT_STATUS_NO_MEMORY;
519                                         goto fail;
520                                 }
521                                 SAFE_FREE(name);
522                                 name = tmp;
523                                 start = name + start_ofs;
524
525                                 /*
526                                  * We just scanned for, and found the end of the path.
527                                  * We must return a valid stat struct if it exists.
528                                  * JRA.
529                                  */
530
531                                 if (SMB_VFS_STAT(conn,name, &st) == 0) {
532                                         *pst = st;
533                                 } else {
534                                         SET_STAT_INVALID(st);
535                                 }
536                         }
537
538                         SAFE_FREE(found_name);
539                 } /* end else */
540
541 #ifdef DEVELOPER
542                 if (VALID_STAT(st) &&
543                     get_delete_on_close_flag(vfs_file_id_from_sbuf(conn, &st))) {
544                         result = NT_STATUS_DELETE_PENDING;
545                         goto fail;
546                 }
547 #endif
548
549                 /* 
550                  * Add to the dirpath that we have resolved so far.
551                  */
552
553                 if (*dirpath != '\0') {
554                         char *tmp;
555
556                         if (asprintf(&tmp, "%s/%s", dirpath, start) == -1) {
557                                 DEBUG(0, ("asprintf failed\n"));
558                                 return NT_STATUS_NO_MEMORY;
559                         }
560                         SAFE_FREE(dirpath);
561                         dirpath = tmp;
562                 }
563                 else {
564                         SAFE_FREE(dirpath);
565                         if (!(dirpath = SMB_STRDUP(start))) {
566                                 DEBUG(0, ("strdup failed\n"));
567                                 return NT_STATUS_NO_MEMORY;
568                         }
569                 }
570
571                 /*
572                  * Don't cache a name with mangled or wildcard components
573                  * as this can change the size.
574                  */
575
576                 if(!component_was_mangled && !name_has_wildcard) {
577                         stat_cache_add(orig_path, dirpath, conn->case_sensitive);
578                 }
579
580                 /*
581                  * Restore the / that we wiped out earlier.
582                  */
583                 if (end) {
584                         *end = '/';
585                 }
586         }
587
588         /*
589          * Don't cache a name with mangled or wildcard components
590          * as this can change the size.
591          */
592
593         if(!component_was_mangled && !name_has_wildcard) {
594                 stat_cache_add(orig_path, name, conn->case_sensitive);
595         }
596
597         /*
598          * The name has been resolved.
599          */
600
601         DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
602
603  done:
604         pstrcpy(orig_path, name);
605         SAFE_FREE(name);
606         SAFE_FREE(dirpath);
607         return NT_STATUS_OK;
608  fail:
609         DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
610         pstrcpy(orig_path, dirpath);
611         pstrcat(orig_path, "/");
612         pstrcat(orig_path, start);
613         SAFE_FREE(name);
614         SAFE_FREE(dirpath);
615         return result;
616 }
617
618 /****************************************************************************
619  Check a filename - possibly calling check_reduced_name.
620  This is called by every routine before it allows an operation on a filename.
621  It does any final confirmation necessary to ensure that the filename is
622  a valid one for the user to access.
623 ****************************************************************************/
624
625 NTSTATUS check_name(connection_struct *conn, const pstring name)
626 {
627         if (IS_VETO_PATH(conn, name))  {
628                 /* Is it not dot or dot dot. */
629                 if (!((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2])))) {
630                         DEBUG(5,("check_name: file path name %s vetoed\n",name));
631                         return map_nt_error_from_unix(ENOENT);
632                 }
633         }
634
635         if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) {
636                 NTSTATUS status = check_reduced_name(conn,name);
637                 if (!NT_STATUS_IS_OK(status)) {
638                         DEBUG(5,("check_name: name %s failed with %s\n",name, nt_errstr(status)));
639                         return status;
640                 }
641         }
642
643         return NT_STATUS_OK;
644 }
645
646 /****************************************************************************
647  Check if two filenames are equal.
648  This needs to be careful about whether we are case sensitive.
649 ****************************************************************************/
650
651 static BOOL fname_equal(const char *name1, const char *name2, BOOL case_sensitive)
652 {
653         /* Normal filename handling */
654         if (case_sensitive)
655                 return(strcmp(name1,name2) == 0);
656
657         return(strequal(name1,name2));
658 }
659
660 /****************************************************************************
661  Scan a directory to find a filename, matching without case sensitivity.
662  If the name looks like a mangled name then try via the mangling functions
663 ****************************************************************************/
664
665 static BOOL scan_directory(connection_struct *conn, const char *path,
666                            char *name, char **found_name)
667 {
668         struct smb_Dir *cur_dir;
669         const char *dname;
670         BOOL mangled;
671         char *unmangled_name = NULL;
672         long curpos;
673
674         mangled = mangle_is_mangled(name, conn->params);
675
676         /* handle null paths */
677         if ((path == NULL) || (*path == 0))
678                 path = ".";
679
680         /*
681          * The incoming name can be mangled, and if we de-mangle it
682          * here it will not compare correctly against the filename (name2)
683          * read from the directory and then mangled by the mangle_map()
684          * call. We need to mangle both names or neither.
685          * (JRA).
686          *
687          * Fix for bug found by Dina Fine. If in case sensitive mode then
688          * the mangle cache is no good (3 letter extension could be wrong
689          * case - so don't demangle in this case - leave as mangled and
690          * allow the mangling of the directory entry read (which is done
691          * case insensitively) to match instead. This will lead to more
692          * false positive matches but we fail completely without it. JRA.
693          */
694
695         if (mangled && !conn->case_sensitive) {
696                 mangled = !mangle_check_cache_alloc(name, &unmangled_name,
697                                                     conn->params);
698                 name = unmangled_name;
699         }
700
701         /* open the directory */
702         if (!(cur_dir = OpenDir(conn, path, NULL, 0))) {
703                 DEBUG(3,("scan dir didn't open dir [%s]\n",path));
704                 SAFE_FREE(unmangled_name);
705                 return(False);
706         }
707
708         /* now scan for matching names */
709         curpos = 0;
710         while ((dname = ReadDirName(cur_dir, &curpos))) {
711
712                 /* Is it dot or dot dot. */
713                 if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) {
714                         continue;
715                 }
716
717                 /*
718                  * At this point dname is the unmangled name.
719                  * name is either mangled or not, depending on the state of the "mangled"
720                  * variable. JRA.
721                  */
722
723                 /*
724                  * Check mangled name against mangled name, or unmangled name
725                  * against unmangled name.
726                  */
727
728                 if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) {
729                         /* we've found the file, change it's name and return */
730                         *found_name = SMB_STRDUP(dname);
731                         SAFE_FREE(unmangled_name);
732                         CloseDir(cur_dir);
733                         return(True);
734                 }
735         }
736
737         SAFE_FREE(unmangled_name);
738         CloseDir(cur_dir);
739         errno = ENOENT;
740         return(False);
741 }