[SCM] SAMBA-CTDB repository - branch v3-2-ctdb updated - 3.2.11-ctdb-64-6-gd4d46eb

Michael Adam obnox at samba.org
Mon Sep 21 08:26:20 MDT 2009


The branch, v3-2-ctdb has been updated
       via  d4d46eb394e15035783cacbe150d3c8638c68f19 (commit)
       via  6f97fbc09b376b0a18b61a38b4e1e85669f0adf9 (commit)
      from  f321f0937e27467b4b3a5d8e2a4336acc95b0efd (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-2-ctdb


- Log -----------------------------------------------------------------
commit d4d46eb394e15035783cacbe150d3c8638c68f19
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Feb 25 12:53:45 2009 -0800

    Fix bug in processing of open modes in POSIX open. Was missing case of "If file exists open. If file doesn't exist error." Damn damn damn. CIFSFS client will have to have fallback cases for this error for a long time. Jeremy.

commit 6f97fbc09b376b0a18b61a38b4e1e85669f0adf9
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 16 03:22:56 2009 +0200

    s3: Fix vfs_shadow_copy2 to allow in-path @GMT-xxx

-----------------------------------------------------------------------

Summary of changes:
 source/modules/vfs_shadow_copy2.c |  115 ++++++++++++++++++++++++++++++++-----
 source/smbd/trans2.c              |    2 +
 2 files changed, 102 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/modules/vfs_shadow_copy2.c b/source/modules/vfs_shadow_copy2.c
index a2b1a3f..1cc7cc4 100644
--- a/source/modules/vfs_shadow_copy2.c
+++ b/source/modules/vfs_shadow_copy2.c
@@ -76,31 +76,99 @@ static int vfs_shadow_copy2_debug_level = DBGC_VFS;
 /*
   make very sure it is one of our special names 
  */
-static inline bool shadow_copy2_match_name(const char *name)
+static inline bool shadow_copy2_match_name(const char *name, const char **gmt_start)
 {
 	unsigned year, month, day, hr, min, sec;
-	if (name[0] != '@') return False;
-	if (strncmp(name, "@GMT-", 5) != 0) return False;
-	if (sscanf(name, "@GMT-%04u.%02u.%02u-%02u.%02u.%02u", &year, &month,
+	const char *p;
+	if (gmt_start) {
+		(*gmt_start) = NULL;
+	}
+	p = strstr_m(name, "@GMT-");
+	if (p == NULL) return false;
+	if (p > name && p[-1] != '/') return False;
+	if (sscanf(p, "@GMT-%04u.%02u.%02u-%02u.%02u.%02u", &year, &month,
 		   &day, &hr, &min, &sec) != 6) {
 		return False;
 	}
-	if (name[24] != 0 && name[24] != '/') {
+	if (p[24] != 0 && p[24] != '/') {
 		return False;
 	}
+	if (gmt_start) {
+		(*gmt_start) = p;
+	}
 	return True;
 }
 
 /*
+  shadow copy paths can also come into the server in this form:
+
+    /foo/bar/@GMT-XXXXX/some/file
+
+  This function normalises the filename to be of the form:
+
+    @GMT-XXXX/foo/bar/some/file
+ */
+static const char *shadow_copy2_normalise_path(TALLOC_CTX *mem_ctx, const char *path, const char *gmt_start)
+{
+	char *pcopy;
+	char buf[GMT_NAME_LEN];
+	size_t prefix_len;
+
+	if (path == gmt_start) {
+		return path;
+	}
+
+	prefix_len = gmt_start - path - 1;
+
+	DEBUG(10, ("path=%s, gmt_start=%s, prefix_len=%d\n", path, gmt_start,
+		   (int)prefix_len));
+
+	/*
+	 * We've got a/b/c/@GMT-YYYY.MM.DD-HH.MM.SS/d/e. convert to
+	 * @GMT-YYYY.MM.DD-HH.MM.SS/a/b/c/d/e before further
+	 * processing. As many VFS calls provide a const char *,
+	 * unfortunately we have to make a copy.
+	 */
+
+	pcopy = talloc_strdup(talloc_tos(), path);
+	if (pcopy == NULL) {
+		return NULL;
+	}
+
+	gmt_start = pcopy + prefix_len;
+
+	/*
+	 * Copy away "@GMT-YYYY.MM.DD-HH.MM.SS"
+	 */
+	memcpy(buf, gmt_start+1, GMT_NAME_LEN);
+
+	/*
+	 * Make space for it including a trailing /
+	 */
+	memmove(pcopy + GMT_NAME_LEN + 1, pcopy, prefix_len);
+
+	/*
+	 * Move in "@GMT-YYYY.MM.DD-HH.MM.SS/" at the beginning again
+	 */
+	memcpy(pcopy, buf, GMT_NAME_LEN);
+	pcopy[GMT_NAME_LEN] = '/';
+
+	DEBUG(10, ("shadow_copy2_normalise_path: %s -> %s\n", path, pcopy));
+
+	return pcopy;
+}
+
+/*
   convert a name to the shadow directory
  */
 
 #define _SHADOW2_NEXT(op, args, rtype, eret, extra) do { \
 	const char *name = fname; \
-	if (shadow_copy2_match_name(fname)) { \
+	const char *gmt_start; \
+	if (shadow_copy2_match_name(fname, &gmt_start)) {	\
 		char *name2; \
 		rtype ret; \
-		name2 = convert_shadow2_name(handle, fname); \
+		name2 = convert_shadow2_name(handle, fname, gmt_start);	\
 		if (name2 == NULL) { \
 			errno = EINVAL; \
 			return eret; \
@@ -121,10 +189,11 @@ static inline bool shadow_copy2_match_name(const char *name)
 
 #define _SHADOW2_NTSTATUS_NEXT(op, args, eret, extra) do { \
         const char *name = fname; \
-        if (shadow_copy2_match_name(fname)) { \
+        const char *gmt_start; \
+        if (shadow_copy2_match_name(fname, &gmt_start)) {	\
                 char *name2; \
                 NTSTATUS ret; \
-                name2 = convert_shadow2_name(handle, fname); \
+                name2 = convert_shadow2_name(handle, fname, gmt_start);	\
                 if (name2 == NULL) { \
                         errno = EINVAL; \
                         return eret; \
@@ -144,7 +213,9 @@ static inline bool shadow_copy2_match_name(const char *name)
 #define SHADOW2_NEXT(op, args, rtype, eret) _SHADOW2_NEXT(op, args, rtype, eret, )
 
 #define SHADOW2_NEXT2(op, args) do { \
-	if (shadow_copy2_match_name(oldname) || shadow_copy2_match_name(newname)) { \
+	const char *gmt_start1, *gmt_start2; \
+	if (shadow_copy2_match_name(oldname, &gmt_start1) || \
+	    shadow_copy2_match_name(newname, &gmt_start2)) {	\
 		errno = EROFS; \
 		return -1; \
 	} else { \
@@ -152,7 +223,6 @@ static inline bool shadow_copy2_match_name(const char *name)
 	} \
 } while (0)
 
-
 /*
   find the mount point of a filesystem
  */
@@ -233,7 +303,7 @@ static const char *shadow_copy2_find_basedir(TALLOC_CTX *mem_ctx, vfs_handle_str
   convert a filename from a share relative path, to a path in the
   snapshot directory
  */
-static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname)
+static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname, const char *gmt_path)
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
 	const char *snapdir, *relpath, *baseoffset, *basedir;
@@ -254,6 +324,14 @@ static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname)
 		return NULL;
 	}
 
+	if (strncmp(fname, "@GMT-", 5) != 0) {
+		fname = shadow_copy2_normalise_path(tmp_ctx, fname, gmt_path);
+		if (fname == NULL) {
+			talloc_free(tmp_ctx);
+			return NULL;
+		}
+	}
+
 	relpath = fname + GMT_NAME_LEN;
 	baselen = strlen(basedir);
 	baseoffset = handle->conn->connectpath + baselen;
@@ -363,7 +441,7 @@ static int shadow_copy2_lstat(vfs_handle_struct *handle,
 static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
 {
 	int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
-	if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
+	if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name, NULL)) {
 		convert_sbuf(handle, fsp->fsp_name, sbuf);
 	}
 	return ret;
@@ -413,6 +491,8 @@ static int shadow_copy2_mknod(vfs_handle_struct *handle,
 static char *shadow_copy2_realpath(vfs_handle_struct *handle,
 			    const char *fname, char *resolved_path)
 {
+	const char *gmt_start;
+
 	/*
 	 * This one here is a bit subtle. SMB_VFS_REALPATH is used in
 	 * smbd in two places: To canonicalize the connection path at
@@ -430,13 +510,18 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle,
 	 * For the tree connect use of REALPATH this will never match
 	 * as here all paths start with "/", not with "@"
 	 */
-	if (shadow_copy2_match_name(fname)) {
+	if (shadow_copy2_match_name(fname, &gmt_start)) {
 		if (fname[GMT_NAME_LEN] == '\0') {
 			return SMB_VFS_NEXT_REALPATH(handle, ".",
 						     resolved_path);
 		}
+		fname = shadow_copy2_normalise_path(talloc_tos(), fname, gmt_start);
+		if (fname == NULL) {
+			return NULL;
+		}
 		fname += GMT_NAME_LEN+1;
 	}
+	DEBUG(10, ("Calling realpath with %s\n", fname));
 	return SMB_VFS_NEXT_REALPATH(handle, fname, resolved_path);
 }
 
@@ -560,7 +645,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
 		SHADOW_COPY_LABEL *tlabels;
 
 		/* ignore names not of the right form in the snapshot directory */
-		if (!shadow_copy2_match_name(d->d_name)) {
+		if (!shadow_copy2_match_name(d->d_name, NULL)) {
 			continue;
 		}
 
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 31fd18d..5b182df 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -6362,6 +6362,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
 		create_disp = FILE_OVERWRITE_IF;
 	} else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
 		create_disp = FILE_OPEN_IF;
+	} else if (wire_open_mode == 0) {
+		create_disp = FILE_OPEN;
 	} else {
 		DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
 			(unsigned int)wire_open_mode ));


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list