mirror of
https://github.com/samba-team/samba.git
synced 2025-01-29 21:47:30 +03:00
r3747: - added some of the infrastructure needed for streams support in pvfs
(the IDL, and the load/save meta-data logic) - changed pvfs_resolve_name() to default to non-wildcard, needing PVFS_RESOLVE_WILDCARD to enable wildcards. Most callers don't want wildcards, so defaulting this way makes more sense. - fixed deletion of EAs
This commit is contained in:
parent
5ed3d68d20
commit
e7afd4403c
@ -110,6 +110,7 @@ struct net_context;
|
||||
struct file_info;
|
||||
|
||||
struct xattr_DosEAs;
|
||||
struct xattr_DosStreams;
|
||||
|
||||
struct test_join;
|
||||
|
||||
|
@ -47,4 +47,23 @@ interface xattr
|
||||
uint16 num_eas;
|
||||
[size_is(num_eas)] xattr_EA *eas;
|
||||
} xattr_DosEAs;
|
||||
|
||||
/* we store stream information in this xattr structure. Then
|
||||
the streams themselves are stored in
|
||||
user.DosStream.STREAMNAME or in external files, according
|
||||
to the flags */
|
||||
const string XATTR_DOSSTREAMS_NAME = "user.DosStreams";
|
||||
|
||||
const int XATTR_STREAM_FLAG_INTERNAL = 0x00000001;
|
||||
|
||||
typedef struct {
|
||||
utf8string name;
|
||||
uint64 size;
|
||||
uint32 flags;
|
||||
} xattr_DosStream;
|
||||
|
||||
typedef [public] struct {
|
||||
uint32 num_streams;
|
||||
[size_is(num_streams)] xattr_DosStream *streams;
|
||||
} xattr_DosStreams;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ ADD_OBJ_FILES = \
|
||||
ntvfs/posix/pvfs_seek.o \
|
||||
ntvfs/posix/pvfs_ioctl.o \
|
||||
ntvfs/posix/pvfs_xattr.o \
|
||||
ntvfs/posix/pvfs_streams.o \
|
||||
ntvfs/common/opendb.o \
|
||||
ntvfs/common/brlock.o
|
||||
# End MODULE ntvfs_posix
|
||||
|
@ -39,8 +39,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
|
||||
}
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -69,8 +68,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
|
||||
struct pvfs_filename *name;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, rd->in.path,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, rd->in.path, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -103,6 +103,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
|
||||
NTSTATUS status;
|
||||
uint32_t create_action;
|
||||
|
||||
if (name->stream_name) {
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
|
||||
/* if the client says it must be a directory, and it isn't,
|
||||
then fail */
|
||||
if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
@ -180,8 +184,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
|
||||
if (mkdir(name->full_name, mode) == -1) {
|
||||
return pvfs_map_errno(pvfs,errno);
|
||||
}
|
||||
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -684,8 +687,7 @@ static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs,
|
||||
struct pvfs_filename *name;
|
||||
NTSTATUS status;
|
||||
|
||||
status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -736,7 +738,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
PVFS_RESOLVE_STREAMS, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -826,8 +828,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
|
||||
}
|
||||
|
||||
/* try re-resolving the name */
|
||||
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -219,8 +219,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
|
||||
NTSTATUS status;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, info->generic.in.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -250,12 +250,14 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
|
||||
struct pvfs_filename *name1, *name2;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1);
|
||||
status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1,
|
||||
PVFS_RESOLVE_WILDCARD, &name1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 0, &name2);
|
||||
status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2,
|
||||
PVFS_RESOLVE_WILDCARD, &name2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -325,10 +327,6 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (name1->has_wildcard || name2->has_wildcard) {
|
||||
return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||
}
|
||||
|
||||
if (!name1->exists) {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
|
||||
case '<':
|
||||
case '?':
|
||||
case '"':
|
||||
if (flags & PVFS_RESOLVE_NO_WILDCARD) {
|
||||
if (!(flags & PVFS_RESOLVE_WILDCARD)) {
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
name->has_wildcard = True;
|
||||
@ -341,7 +341,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t
|
||||
}
|
||||
}
|
||||
if (err_count) {
|
||||
if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--;
|
||||
if (flags & PVFS_RESOLVE_WILDCARD) err_count--;
|
||||
|
||||
if (err_count==1) {
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
|
@ -300,7 +300,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
|
||||
pattern = io->search_first.in.pattern;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -436,7 +436,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
|
||||
max_count = io->t2ffirst.in.max_count;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
|
||||
}
|
||||
|
||||
/* resolve the new name */
|
||||
status = pvfs_resolve_name(pvfs, name, new_name, PVFS_RESOLVE_NO_WILDCARD, &name2);
|
||||
status = pvfs_resolve_name(pvfs, name, new_name, 0, &name2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -144,6 +144,17 @@ static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs,
|
||||
ealist->num_eas++;
|
||||
|
||||
save:
|
||||
/* pull out any null EAs */
|
||||
for (i=0;i<ealist->num_eas;i++) {
|
||||
if (ealist->eas[i].value.length == 0) {
|
||||
memmove(&ealist->eas[i],
|
||||
&ealist->eas[i+1],
|
||||
(ealist->num_eas-(i+1)) * sizeof(ealist->eas[i]));
|
||||
ealist->num_eas--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
status = pvfs_doseas_save(pvfs, name, fd, ealist);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
@ -348,8 +359,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
|
||||
struct utimbuf unix_times;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, info->generic.file.fname,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
27
source/ntvfs/posix/pvfs_streams.c
Normal file
27
source/ntvfs/posix/pvfs_streams.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
POSIX NTVFS backend - alternate data streams
|
||||
|
||||
Copyright (C) Andrew Tridgell 2004
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "vfs_posix.h"
|
||||
#include "librpc/gen_ndr/ndr_xattr.h"
|
||||
|
@ -85,7 +85,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
|
||||
uint_t ofs;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, unl->in.pattern,
|
||||
PVFS_RESOLVE_WILDCARD, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -276,3 +276,40 @@ NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, i
|
||||
return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSEAS_NAME, eas,
|
||||
(ndr_push_flags_fn_t)ndr_push_xattr_DosEAs);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
load the set of streams from extended attributes
|
||||
*/
|
||||
NTSTATUS pvfs_streams_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
|
||||
struct xattr_DosStreams *streams)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ZERO_STRUCTP(streams);
|
||||
if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
status = pvfs_xattr_ndr_load(pvfs, streams, name->full_name, fd,
|
||||
XATTR_DOSSTREAMS_NAME,
|
||||
streams,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_xattr_DosStreams);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
save the set of streams into filesystem xattr
|
||||
*/
|
||||
NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
|
||||
struct xattr_DosStreams *streams)
|
||||
{
|
||||
if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
return pvfs_xattr_ndr_save(pvfs, name->full_name, fd,
|
||||
XATTR_DOSSTREAMS_NAME,
|
||||
streams,
|
||||
(ndr_push_flags_fn_t)ndr_push_xattr_DosStreams);
|
||||
}
|
||||
|
@ -161,8 +161,7 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs,
|
||||
NTSTATUS status;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, cp->in.path,
|
||||
PVFS_RESOLVE_NO_WILDCARD, &name);
|
||||
status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ struct pvfs_mangle_context {
|
||||
|
||||
|
||||
/* flags to pvfs_resolve_name() */
|
||||
#define PVFS_RESOLVE_NO_WILDCARD (1<<0)
|
||||
#define PVFS_RESOLVE_WILDCARD (1<<0)
|
||||
#define PVFS_RESOLVE_STREAMS (1<<1)
|
||||
|
||||
/* flags in pvfs->flags */
|
||||
|
Loading…
x
Reference in New Issue
Block a user