diff options
author | Volker Lendecke <vl@samba.org> | 2009-02-02 11:52:08 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-06-02 11:58:22 +0200 |
commit | 84090c95a5851d71bf61388281547041f9c0b277 (patch) | |
tree | 5817f8fc7b4543b1f09e1ab59fff1e3413d0cb7a /source3/modules | |
parent | 56efcb7b723b581b9c258d137331a171512d4d09 (diff) | |
download | samba-84090c95a5851d71bf61388281547041f9c0b277.tar.gz samba-84090c95a5851d71bf61388281547041f9c0b277.tar.bz2 samba-84090c95a5851d71bf61388281547041f9c0b277.zip |
Add a "connectpath" operation to the shadow_copy2 module
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/vfs_shadow_copy2.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index acfac57b51..030d3e2b01 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -416,6 +416,59 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle, SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, NULL); } +static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle, + const char *fname) +{ + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + const char *snapdir, *baseoffset, *basedir; + size_t baselen; + char *ret; + + if (!shadow_copy2_match_name(fname)) { + return handle->conn->connectpath; + } + + snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); + if (snapdir == NULL) { + DEBUG(2,("no snapdir found for share at %s\n", + handle->conn->connectpath)); + TALLOC_FREE(tmp_ctx); + return NULL; + } + + basedir = shadow_copy2_find_basedir(tmp_ctx, handle); + if (basedir == NULL) { + DEBUG(2,("no basedir found for share at %s\n", + handle->conn->connectpath)); + TALLOC_FREE(tmp_ctx); + return NULL; + } + + baselen = strlen(basedir); + baseoffset = handle->conn->connectpath + baselen; + + /* some sanity checks */ + if (strncmp(basedir, handle->conn->connectpath, baselen) != 0 || + (handle->conn->connectpath[baselen] != 0 + && handle->conn->connectpath[baselen] != '/')) { + DEBUG(0,("shadow_copy2_connectpath: basedir %s is not a " + "parent of %s\n", basedir, + handle->conn->connectpath)); + TALLOC_FREE(tmp_ctx); + return NULL; + } + + if (*baseoffset == '/') baseoffset++; + + ret = talloc_asprintf(talloc_tos(), "%s/%.*s/%s", + snapdir, + GMT_NAME_LEN, fname, + baseoffset); + DEBUG(6,("shadow_copy2_connectpath: '%s' -> '%s'\n", fname, ret)); + TALLOC_FREE(tmp_ctx); + return ret; +} + static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, const char *fname, uint32 security_info, struct security_descriptor **ppdesc) @@ -592,6 +645,7 @@ static vfs_op_tuple shadow_copy2_ops[] = { {SMB_VFS_OP(shadow_copy2_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(shadow_copy2_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(shadow_copy2_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(shadow_copy2_connectpath), SMB_VFS_OP_CONNECTPATH, SMB_VFS_LAYER_OPAQUE}, /* NT File ACL operations */ {SMB_VFS_OP(shadow_copy2_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, |