}
/**
- * Strip a snapshot component from a filename as
- * handed in via the smb layer.
- * Returns the parsed timestamp and the stripped filename.
+ * This function does two things.
+ *
+ * 1). Checks if an incoming filename is already a
+ * snapshot converted pathname.
+ * If so, it returns the pathname truncated
+ * at the snapshot point which will be used
+ * as the connectpath, and then does an early return.
+ *
+ * 2). Checks if an incoming filename contains an
+ * SMB-layer @GMT- style timestamp.
+ * If so, it strips the timestamp, and returns
+ * both the timestamp and the stripped path
+ * (making it cwd-relative).
*/
+
static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
struct vfs_handle_struct *handle,
const char *orig_name,
char *stripped = NULL;
size_t rest_len, dst_len;
struct shadow_copy2_config *config;
- const char *snapdir;
- ssize_t snapdirlen;
ptrdiff_t len_before_gmt;
const char *name = orig_name;
+ char *abs_path = NULL;
+ bool ret = true;
+ bool already_converted = false;
+ int err = 0;
SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config,
return false);
DEBUG(10, (__location__ ": enter path '%s'\n", name));
+ abs_path = make_path_absolute(mem_ctx, config, name);
+ if (abs_path == NULL) {
+ ret = false;
+ goto out;
+ }
+ name = abs_path;
+
+ DEBUG(10, (__location__ ": abs path '%s'\n", name));
+
+ err = check_for_converted_path(mem_ctx,
+ handle,
+ config,
+ abs_path,
+ &already_converted,
+ psnappath);
+ if (err != 0) {
+ /* error in conversion. */
+ ret = false;
+ goto out;
+ }
+
+ if (already_converted) {
+ goto out;
+ }
+
+ /*
+ * From here we're only looking to strip an
+ * SMB-layer @GMT- token.
+ */
+
p = strstr_m(name, "@GMT-");
if (p == NULL) {
DEBUG(11, ("@GMT not found\n"));
- goto no_snapshot;
+ goto out;
}
if ((p > name) && (p[-1] != '/')) {
/* the GMT-token does not start a path-component */
DEBUG(10, ("not at start, p=%p, name=%p, p[-1]=%d\n",
p, name, (int)p[-1]));
- goto no_snapshot;
+ goto out;
}
- /*
- * Figure out whether we got an already converted string. One
- * case where this happens is in a smb2 create call with the
- * mxac create blob set. We do the get_acl call on
- * fsp->fsp_name, which is already converted. We are converted
- * if we got a file name of the form ".snapshots/@GMT-",
- * i.e. ".snapshots/" precedes "p".
- */
-
- snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir",
- ".snapshots");
- snapdirlen = strlen(snapdir);
len_before_gmt = p - name;
- if ((len_before_gmt >= (snapdirlen + 1)) && (p[-1] == '/')) {
- const char *parent_snapdir = p - (snapdirlen+1);
-
- DEBUG(10, ("parent_snapdir = %s\n", parent_snapdir));
-
- if (strncmp(parent_snapdir, snapdir, snapdirlen) == 0) {
- DEBUG(10, ("name=%s is already converted\n", name));
- goto no_snapshot;
- }
- }
q = strptime(p, GMT_FORMAT, &tm);
if (q == NULL) {
DEBUG(10, ("strptime failed\n"));
- goto no_snapshot;
+ goto out;
}
tm.tm_isdst = -1;
timestamp = timegm(&tm);
if (timestamp == (time_t)-1) {
DEBUG(10, ("timestamp==-1\n"));
- goto no_snapshot;
+ goto out;
}
if (q[0] == '\0') {
/*
* with a path prefix.
*/
if (pstripped != NULL) {
+ if (len_before_gmt > 0) {
+ /*
+ * There is a slash before
+ * the @GMT-. Remove it.
+ */
+ len_before_gmt -= 1;
+ }
stripped = talloc_strndup(mem_ctx, name, p - name);
if (stripped == NULL) {
- return false;
+ ret = false;
+ goto out;
+ }
+ if (orig_name[0] != '/') {
+ if (make_relative_path(config->shadow_cwd,
+ stripped) == false) {
+ DEBUG(10, (__location__ ": path '%s' "
+ "doesn't start with cwd '%s\n",
+ stripped, config->shadow_cwd));
+ ret = false;
+ errno = ENOENT;
+ goto out;
+ }
}
*pstripped = stripped;
}
*ptimestamp = timestamp;
- return true;
+ goto out;
}
if (q[0] != '/') {
/*
* component continues after the gmt-token.
*/
DEBUG(10, ("q[0] = %d\n", (int)q[0]));
- goto no_snapshot;
+ goto out;
}
q += 1;
rest_len = strlen(q);
dst_len = (p-name) + rest_len;
- if (config->snapdirseverywhere) {
- char *insert;
- bool have_insert;
- insert = shadow_copy2_insert_string(talloc_tos(), handle,
- timestamp);
- if (insert == NULL) {
- errno = ENOMEM;
- return false;
- }
-
- DEBUG(10, (__location__ ": snapdirseverywhere mode.\n"
- "path '%s'.\n"
- "insert string '%s'\n", name, insert));
-
- have_insert = (strstr(name, insert+1) != NULL);
- DEBUG(10, ("have_insert=%d, name=%s, insert+1=%s\n",
- (int)have_insert, name, insert+1));
- if (have_insert) {
- DEBUG(10, (__location__ ": insert string '%s' found in "
- "path '%s' found in snapdirseverywhere mode "
- "==> already converted\n", insert, name));
- TALLOC_FREE(insert);
- goto no_snapshot;
- }
- TALLOC_FREE(insert);
- } else {
- char *snapshot_path;
- char *s;
-
- snapshot_path = shadow_copy2_snapshot_path(talloc_tos(),
- handle,
- timestamp);
- if (snapshot_path == NULL) {
- errno = ENOMEM;
- return false;
- }
-
- DEBUG(10, (__location__ " path: '%s'.\n"
- "snapshot path: '%s'\n", name, snapshot_path));
-
- s = strstr(name, snapshot_path);
- if (s == name) {
- /*
- * this starts with "snapshot_basepath/GMT-Token"
- * so it is already a converted absolute
- * path. Don't process further.
- */
- DEBUG(10, (__location__ ": path '%s' starts with "
- "snapshot path '%s' (not in "
- "snapdirseverywhere mode) ==> "
- "already converted\n", name, snapshot_path));
- talloc_free(snapshot_path);
- goto no_snapshot;
- }
- talloc_free(snapshot_path);
- }
-
if (pstripped != NULL) {
stripped = talloc_array(mem_ctx, char, dst_len+1);
if (stripped == NULL) {
- errno = ENOMEM;
- return false;
+ ret = false;
+ goto out;
}
if (p > name) {
memcpy(stripped, name, p-name);
memcpy(stripped + (p-name), q, rest_len);
}
stripped[dst_len] = '\0';
+ if (orig_name[0] != '/') {
+ if (make_relative_path(config->shadow_cwd,
+ stripped) == false) {
+ DEBUG(10, (__location__ ": path '%s' "
+ "doesn't start with cwd '%s\n",
+ stripped, config->shadow_cwd));
+ ret = false;
+ errno = ENOENT;
+ goto out;
+ }
+ }
*pstripped = stripped;
}
*ptimestamp = timestamp;
- return true;
-no_snapshot:
- *ptimestamp = 0;
- return true;
+ ret = true;
+
+ out:
+ TALLOC_FREE(abs_path);
+ return ret;
}
static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,