smbd: Remove non_widelink_open() support code
[samba.git] / source3 / smbd / vfs.c
index 13f5abaffec73fdb2c17ee549834b9de8462df43..1d9f70bafc9a30a0e8bf993501d5c62cf22d4318 100644 (file)
@@ -1122,221 +1122,6 @@ struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
        return result;
 }
 
-/*******************************************************************
- Reduce a file name, removing .. elements and checking that
- it is below dir in the hierarchy. This uses realpath.
-
- If cwd_name == NULL then fname is a client given path relative
- to the root path of the share.
-
- If cwd_name != NULL then fname is a client given path relative
- to cwd_name. cwd_name is relative to the root path of the share.
-********************************************************************/
-
-NTSTATUS check_reduced_name(connection_struct *conn,
-                               const struct smb_filename *cwd_fname,
-                               const struct smb_filename *smb_fname)
-{
-       TALLOC_CTX *ctx = talloc_tos();
-       const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
-       const char *fname = smb_fname->base_name;
-       struct smb_filename *resolved_fname;
-       char *resolved_name = NULL;
-       char *new_fname = NULL;
-       bool allow_symlinks = true;
-       const char *conn_rootdir;
-       size_t rootdir_len;
-       bool parent_dir_checked = false;
-
-       DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
-
-       resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
-
-       if (resolved_fname == NULL) {
-               NTSTATUS status;
-               struct smb_filename *dir_fname = NULL;
-               struct smb_filename *last_component = NULL;
-
-               if (errno == ENOTDIR) {
-                       DBG_NOTICE("Component not a directory in getting "
-                                  "realpath for %s\n",
-                                  fname);
-                       return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-               }
-               if (errno != ENOENT) {
-                       status = map_nt_error_from_unix(errno);
-                       DBG_NOTICE("couldn't get realpath for %s: %s\n",
-                                  fname,
-                                  strerror(errno));
-                       return status;
-               }
-
-               /* errno == ENOENT */
-
-               /*
-                * Last component didn't exist. Remove it and try and
-                * canonicalise the directory name.
-                */
-
-               status = SMB_VFS_PARENT_PATHNAME(conn,
-                                                ctx,
-                                                smb_fname,
-                                                &dir_fname,
-                                                &last_component);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               resolved_fname = SMB_VFS_REALPATH(conn, ctx, dir_fname);
-               if (resolved_fname == NULL) {
-                       status = map_nt_error_from_unix(errno);
-
-                       if (errno == ENOENT || errno == ENOTDIR) {
-                               status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
-                       }
-
-                       DBG_NOTICE("couldn't get realpath for "
-                                  "%s (%s)\n",
-                                  smb_fname_str_dbg(dir_fname),
-                                  nt_errstr(status));
-                       return status;
-               }
-               resolved_name = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               resolved_fname->base_name,
-                                               last_component->base_name);
-               if (resolved_name == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               parent_dir_checked = true;
-       } else {
-               resolved_name = resolved_fname->base_name;
-       }
-
-       DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
-                 resolved_name));
-
-       if (*resolved_name != '/') {
-               DEBUG(0,("check_reduced_name: realpath doesn't return "
-                        "absolute paths !\n"));
-               TALLOC_FREE(resolved_fname);
-               return NT_STATUS_OBJECT_NAME_INVALID;
-       }
-
-       /* Common widelinks and symlinks checks. */
-       conn_rootdir = SMB_VFS_CONNECTPATH(conn, NULL, smb_fname);
-       if (conn_rootdir == NULL) {
-               DBG_NOTICE("Could not get conn_rootdir\n");
-               TALLOC_FREE(resolved_fname);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       rootdir_len = strlen(conn_rootdir);
-
-       /*
-        * In the case of rootdir_len == 1, we know that
-        * conn_rootdir is "/", and we also know that
-        * resolved_name starts with a slash.  So, in this
-        * corner case, resolved_name is automatically a
-        * sub-directory of the conn_rootdir. Thus we can skip
-        * the string comparison and the next character checks
-        * (which are even wrong in this case).
-        */
-       if (rootdir_len != 1) {
-               bool matched;
-
-               matched = (strncmp(conn_rootdir, resolved_name,
-                               rootdir_len) == 0);
-               if (!matched || (resolved_name[rootdir_len] != '/' &&
-                                resolved_name[rootdir_len] != '\0')) {
-                       DBG_NOTICE("Bad access attempt: %s is a symlink "
-                               "outside the "
-                               "share path\n"
-                               "conn_rootdir =%s\n"
-                               "resolved_name=%s\n",
-                               fname,
-                               conn_rootdir,
-                               resolved_name);
-                       TALLOC_FREE(resolved_fname);
-                       if (parent_dir_checked) {
-                               /* Part of a component path. */
-                               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-                       } else {
-                               /* End of a path. */
-                               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-                       }
-               }
-       }
-
-       /* Extra checks if all symlinks are disallowed. */
-       allow_symlinks = lp_follow_symlinks(SNUM(conn));
-       if (!allow_symlinks) {
-               /* fname can't have changed in resolved_path. */
-               const char *p = &resolved_name[rootdir_len];
-
-               /*
-                * UNIX filesystem semantics, names consisting
-                * only of "." or ".." CANNOT be symlinks.
-                */
-               if (ISDOT(fname) || ISDOTDOT(fname)) {
-                       goto out;
-               }
-
-               if (*p != '/') {
-                       DBG_NOTICE("logic error (%c) "
-                               "in resolved_name: %s\n",
-                               *p,
-                               fname);
-                       TALLOC_FREE(resolved_fname);
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-
-               p++;
-
-               /*
-                * If cwd_name is present and not ".",
-                * then fname is relative to that, not
-                * the root of the share. Make sure the
-                * path we check is the one the client
-                * sent (cwd_name+fname).
-                */
-               if (cwd_name != NULL && !ISDOT(cwd_name)) {
-                       new_fname = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               cwd_name,
-                                               fname);
-                       if (new_fname == NULL) {
-                               TALLOC_FREE(resolved_fname);
-                               return NT_STATUS_NO_MEMORY;
-                       }
-                       fname = new_fname;
-               }
-
-               if (strcmp(fname, p)!=0) {
-                       DBG_NOTICE("Bad access "
-                               "attempt: %s is a symlink to %s\n",
-                               fname,
-                               p);
-                       TALLOC_FREE(resolved_fname);
-                       TALLOC_FREE(new_fname);
-                       if (parent_dir_checked) {
-                               /* Part of a component path. */
-                               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
-                       } else {
-                               /* End of a path. */
-                               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-                       }
-               }
-       }
-
-  out:
-
-       DBG_INFO("%s reduced to %s\n", fname, resolved_name);
-       TALLOC_FREE(resolved_fname);
-       TALLOC_FREE(new_fname);
-       return NT_STATUS_OK;
-}
-
 /*
  * Ensure LSTAT is called for POSIX paths.
  */