Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/filename.c

    r599 r745  
    2626
    2727#include "includes.h"
     28#include "system/filesys.h"
     29#include "fake_file.h"
     30#include "smbd/smbd.h"
    2831
    2932static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
     
    9699                }
    97100        }
     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
     114static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
     115                                connection_struct *conn,
     116                                bool posix_pathnames,
     117                                const struct smb_filename *smb_fname,
     118                                char **pp_dirpath,
     119                                char **pp_start)
     120{
     121        struct smb_filename parent_fname;
     122        const char *last_component = NULL;
     123        NTSTATUS status;
     124        int ret;
     125
     126        ZERO_STRUCT(parent_fname);
     127        if (!parent_dirname(ctx, smb_fname->base_name,
     128                                &parent_fname.base_name,
     129                                &last_component)) {
     130                return NT_STATUS_NO_MEMORY;
     131        }
     132
     133        /*
     134         * If there was no parent component in
     135         * smb_fname->base_name of the parent name
     136         * contained a wildcard then don't do this
     137         * optimization.
     138         */
     139        if ((smb_fname->base_name == last_component) ||
     140                        ms_has_wild(parent_fname.base_name)) {
     141                return NT_STATUS_OK;
     142        }
     143
     144        if (posix_pathnames) {
     145                ret = SMB_VFS_LSTAT(conn, &parent_fname);
     146        } else {
     147                ret = SMB_VFS_STAT(conn, &parent_fname);
     148        }
     149
     150        /* If the parent stat failed, just continue
     151           with the normal tree walk. */
     152
     153        if (ret == -1) {
     154                return NT_STATUS_OK;
     155        }
     156
     157        status = check_for_dot_component(&parent_fname);
     158        if (!NT_STATUS_IS_OK(status)) {
     159                return status;
     160        }
     161
     162        /* Parent exists - set "start" to be the
     163         * last compnent to shorten the tree walk. */
     164
     165        /*
     166         * Safe to use CONST_DISCARD
     167         * here as last_component points
     168         * into our smb_fname->base_name.
     169         */
     170        *pp_start = CONST_DISCARD(char *,last_component);
     171
     172        /* Update dirpath. */
     173        TALLOC_FREE(*pp_dirpath);
     174        *pp_dirpath = talloc_strdup(ctx, parent_fname.base_name);
     175        if (!*pp_dirpath) {
     176                return NT_STATUS_NO_MEMORY;
     177        }
     178
     179        DEBUG(5,("check_parent_exists: name "
     180                "= %s, dirpath = %s, "
     181                "start = %s\n",
     182                smb_fname->base_name,
     183                *pp_dirpath,
     184                *pp_start));
     185
    98186        return NT_STATUS_OK;
    99187}
     
    285373
    286374        /*
    287          * If we're providing case insentive semantics or
     375         * If we're providing case insensitive semantics or
    288376         * the underlying filesystem is case insensitive,
    289377         * then a case-normalized hit in the stat-cache is
     
    303391        /*
    304392         * Make sure "dirpath" is an allocated string, we use this for
    305          * building the directories with asprintf and free it.
     393         * building the directories with talloc_asprintf and free it.
    306394         */
    307395
     
    356444                SET_STAT_INVALID(smb_fname->st);
    357445
     446                if (errno == ENOENT) {
     447                        /* Optimization when creating a new file - only
     448                           the last component doesn't exist. */
     449                        status = check_parent_exists(ctx,
     450                                                conn,
     451                                                posix_pathnames,
     452                                                smb_fname,
     453                                                &dirpath,
     454                                                &start);
     455                        if (!NT_STATUS_IS_OK(status)) {
     456                                goto fail;
     457                        }
     458                }
     459
    358460                /*
    359461                 * A special case - if we don't have any wildcards or mangling chars and are case
    360                  * sensitive or the underlying filesystem is case insentive then searching
     462                 * sensitive or the underlying filesystem is case insensitive then searching
    361463                 * won't help.
    362464                 */
     
    385487                                 */
    386488                                struct smb_filename parent_fname;
     489                                const char *last_component = NULL;
     490
    387491                                ZERO_STRUCT(parent_fname);
    388492                                if (!parent_dirname(ctx, smb_fname->base_name,
    389493                                                        &parent_fname.base_name,
    390                                                         NULL)) {
     494                                                        &last_component)) {
    391495                                        status = NT_STATUS_NO_MEMORY;
    392496                                        goto fail;
     
    405509                                        }
    406510                                }
     511
    407512                                /*
    408513                                 * Missing last component is ok - new file.
     
    412517                                goto done;
    413518                        }
     519                }
     520        } else {
     521                /*
     522                 * We have a wildcard in the pathname.
     523                 *
     524                 * Optimization for common case where the wildcard
     525                 * is in the last component and the client already
     526                 * sent the correct case.
     527                 */
     528                status = check_parent_exists(ctx,
     529                                        conn,
     530                                        posix_pathnames,
     531                                        smb_fname,
     532                                        &dirpath,
     533                                        &start);
     534                if (!NT_STATUS_IS_OK(status)) {
     535                        goto fail;
    414536                }
    415537        }
     
    481603                        status = NT_STATUS_OBJECT_NAME_INVALID;
    482604                        goto fail;
     605                }
     606
     607                /* Skip the stat call if it's a wildcard end. */
     608                if (name_has_wildcard) {
     609                        DEBUG(5,("Wildcard %s\n",start));
     610                        goto done;
    483611                }
    484612
     
    735863                if (VALID_STAT(smb_fname->st)) {
    736864                        bool delete_pending;
     865                        uint32_t name_hash;
     866
     867                        status = file_name_hash(conn,
     868                                        smb_fname_str_dbg(smb_fname),
     869                                        &name_hash);
     870                        if (!NT_STATUS_IS_OK(status)) {
     871                                goto fail;
     872                        }
     873
    737874                        get_file_infos(vfs_file_id_from_sbuf(conn,
    738875                                                             &smb_fname->st),
     876                                       name_hash,
    739877                                       &delete_pending, NULL);
    740878                        if (delete_pending) {
Note: See TracChangeset for help on using the changeset viewer.