summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-11-15 06:57:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:50 -0500
commit187412f3da4fbc6feeca15bd0c2527534255964e (patch)
treebd09f3cab5515bd89233a509d2a42238894f24eb
parent4719461a07a5494f01b4295e6f9e0479ea8e96a0 (diff)
downloadsamba-187412f3da4fbc6feeca15bd0c2527534255964e.tar.gz
samba-187412f3da4fbc6feeca15bd0c2527534255964e.tar.bz2
samba-187412f3da4fbc6feeca15bd0c2527534255964e.zip
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 used to be commit e7afd4403cc1b7e0928776929f8988aa6f15640b)
-rw-r--r--source4/include/structs.h1
-rw-r--r--source4/librpc/idl/xattr.idl19
-rw-r--r--source4/ntvfs/posix/config.mk1
-rw-r--r--source4/ntvfs/posix/pvfs_mkdir.c6
-rw-r--r--source4/ntvfs/posix/pvfs_open.c17
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c3
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c10
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c4
-rw-r--r--source4/ntvfs/posix/pvfs_search.c4
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c16
-rw-r--r--source4/ntvfs/posix/pvfs_streams.c27
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c3
-rw-r--r--source4/ntvfs/posix/pvfs_xattr.c37
-rw-r--r--source4/ntvfs/posix/vfs_posix.c3
-rw-r--r--source4/ntvfs/posix/vfs_posix.h2
15 files changed, 122 insertions, 31 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h
index 424b7a0e7a..229c489072 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -110,6 +110,7 @@ struct net_context;
struct file_info;
struct xattr_DosEAs;
+struct xattr_DosStreams;
struct test_join;
diff --git a/source4/librpc/idl/xattr.idl b/source4/librpc/idl/xattr.idl
index 0fc965c825..be587ffb88 100644
--- a/source4/librpc/idl/xattr.idl
+++ b/source4/librpc/idl/xattr.idl
@@ -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;
}
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 74e991d9bd..1d33d8b381 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -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
diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c
index 3b5204c934..1bc0fa569e 100644
--- a/source4/ntvfs/posix/pvfs_mkdir.c
+++ b/source4/ntvfs/posix/pvfs_mkdir.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 9bb3487679..4f089a8c07 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -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;
}
@@ -735,8 +737,8 @@ 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);
+ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
+ 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;
}
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index c8134939a3..3eaa7865e8 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index aae17f327c..efaf63ba9d 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index 354cdd4bb4..576b0d9db4 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -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;
diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c
index 831b799716..f805f201f6 100644
--- a/source4/ntvfs/posix/pvfs_search.c
+++ b/source4/ntvfs/posix/pvfs_search.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index b9ed592bf4..7ba64979c3 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c
new file mode 100644
index 0000000000..b71ff640e5
--- /dev/null
+++ b/source4/ntvfs/posix/pvfs_streams.c
@@ -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"
+
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index ab8f1abf62..8dc9f60ad8 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c
index d5a7d17a31..269a2cc863 100644
--- a/source4/ntvfs/posix/pvfs_xattr.c
+++ b/source4/ntvfs/posix/pvfs_xattr.c
@@ -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);
+}
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index e5712e3e7d..2b4eef04ba 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 46cc38c1f8..645d293a6d 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -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 */