#include "includes.h"
+#include "smbd/smbd.h"
/* cap functions */
static char *capencode(TALLOC_CTX *ctx, const char *from);
return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
}
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
SMB_STRUCT_DIRENT *newdirent;
}
DEBUG(3,("cap: cap_readdir: %s\n", newname));
newnamelen = strlen(newname)+1;
- newdirent = (SMB_STRUCT_DIRENT *)TALLOC_ARRAY(talloc_tos(),
+ newdirent = (SMB_STRUCT_DIRENT *)talloc_array(talloc_tos(),
char,
sizeof(SMB_STRUCT_DIRENT)+
newnamelen);
return ret;
}
-static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
+static int cap_rename(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname_src,
+ const struct smb_filename *smb_fname_dst)
{
- char *capold = capencode(talloc_tos(), oldname);
- char *capnew = capencode(talloc_tos(), newname);
+ char *capold = NULL;
+ char *capnew = NULL;
+ struct smb_filename *smb_fname_src_tmp = NULL;
+ struct smb_filename *smb_fname_dst_tmp = NULL;
+ NTSTATUS status;
+ int ret = -1;
+ capold = capencode(talloc_tos(), smb_fname_src->base_name);
+ capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
if (!capold || !capnew) {
errno = ENOMEM;
- return -1;
+ goto out;
+ }
+
+ /* Setup temporary smb_filename structs. */
+ status = copy_smb_filename(talloc_tos(), smb_fname_src,
+ &smb_fname_src_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto out;
}
- return SMB_VFS_NEXT_RENAME(handle, capold, capnew);
+ status = copy_smb_filename(talloc_tos(), smb_fname_dst,
+ &smb_fname_dst_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ goto out;
+ }
+
+ smb_fname_src_tmp->base_name = capold;
+ smb_fname_dst_tmp->base_name = capnew;
+
+ ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
+ smb_fname_dst_tmp);
+ out:
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(smb_fname_src_tmp);
+ TALLOC_FREE(smb_fname_dst_tmp);
+
+ return ret;
}
-static int cap_stat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
+static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *cappath;
+ char *tmp_base_name = NULL;
+ int ret;
+
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_STAT(handle, cappath, sbuf);
+
+ tmp_base_name = smb_fname->base_name;
+ smb_fname->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+
+ smb_fname->base_name = tmp_base_name;
+ TALLOC_FREE(cappath);
+
+ return ret;
}
-static int cap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
+static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *cappath;
+ char *tmp_base_name = NULL;
+ int ret;
+
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LSTAT(handle, cappath, sbuf);
+
+ tmp_base_name = smb_fname->base_name;
+ smb_fname->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+
+ smb_fname->base_name = tmp_base_name;
+ TALLOC_FREE(cappath);
+
+ return ret;
}
-static int cap_unlink(vfs_handle_struct *handle, const char *path)
+static int cap_unlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *smb_fname_tmp = NULL;
+ char *cappath = NULL;
+ NTSTATUS status;
+ int ret;
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_UNLINK(handle, cappath);
+
+ /* Setup temporary smb_filename structs. */
+ status = copy_smb_filename(talloc_tos(), smb_fname,
+ &smb_fname_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ smb_fname_tmp->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
+
+ TALLOC_FREE(smb_fname_tmp);
+ return ret;
}
static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
return SMB_VFS_NEXT_CHDIR(handle, cappath);
}
-static int cap_ntimes(vfs_handle_struct *handle, const char *path,
+static int cap_ntimes(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
struct smb_file_time *ft)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *smb_fname_tmp = NULL;
+ char *cappath = NULL;
+ NTSTATUS status;
+ int ret;
+
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_NTIMES(handle, cappath, ft);
+
+ /* Setup temporary smb_filename structs. */
+ status = copy_smb_filename(talloc_tos(), smb_fname,
+ &smb_fname_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ smb_fname_tmp->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
+
+ TALLOC_FREE(smb_fname_tmp);
+ return ret;
}
-static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
+ const char *newpath)
{
char *capold = capencode(talloc_tos(), oldpath);
char *capnew = capencode(talloc_tos(), newpath);
return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
}
-static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle, const char *path,
+ char *buf, size_t bufsiz)
{
char *cappath = capencode(talloc_tos(), path);
return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev);
}
-static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
+static char *cap_realpath(vfs_handle_struct *handle, const char *path)
{
/* monyo need capencode'ed and capdecode'ed? */
char *cappath = capencode(talloc_tos(), path);
errno = ENOMEM;
return NULL;
}
- return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
+ return SMB_VFS_NEXT_REALPATH(handle, cappath);
}
static int cap_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
char *cappath = capencode(talloc_tos(), path);
/* If the underlying VFS doesn't have ACL support... */
- if (!handle->vfs_next.ops.chmod_acl) {
- errno = ENOSYS;
- return -1;
- }
if (!cappath) {
errno = ENOMEM;
return -1;
return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
}
-/* VFS operations structure */
-
-static vfs_op_tuple cap_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(cap_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Directory operations */
-
- {SMB_VFS_OP(cap_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {SMB_VFS_OP(cap_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
-
- {SMB_VFS_OP(cap_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(cap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* EA operations. */
- {SMB_VFS_OP(cap_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+static struct vfs_fn_pointers vfs_cap_fns = {
+ .disk_free = cap_disk_free,
+ .opendir = cap_opendir,
+ .readdir = cap_readdir,
+ .mkdir = cap_mkdir,
+ .rmdir = cap_rmdir,
+ .open_fn = cap_open,
+ .rename = cap_rename,
+ .stat = cap_stat,
+ .lstat = cap_lstat,
+ .unlink = cap_unlink,
+ .chmod = cap_chmod,
+ .chown = cap_chown,
+ .lchown = cap_lchown,
+ .chdir = cap_chdir,
+ .ntimes = cap_ntimes,
+ .symlink = cap_symlink,
+ .vfs_readlink = cap_readlink,
+ .link = cap_link,
+ .mknod = cap_mknod,
+ .realpath = cap_realpath,
+ .chmod_acl = cap_chmod_acl,
+ .sys_acl_get_file = cap_sys_acl_get_file,
+ .sys_acl_set_file = cap_sys_acl_set_file,
+ .sys_acl_delete_def_file = cap_sys_acl_delete_def_file,
+ .getxattr = cap_getxattr,
+ .lgetxattr = cap_lgetxattr,
+ .fgetxattr = cap_fgetxattr,
+ .listxattr = cap_listxattr,
+ .llistxattr = cap_llistxattr,
+ .removexattr = cap_removexattr,
+ .lremovexattr = cap_lremovexattr,
+ .fremovexattr = cap_fremovexattr,
+ .setxattr = cap_setxattr,
+ .lsetxattr = cap_lsetxattr,
+ .fsetxattr = cap_fsetxattr
};
NTSTATUS vfs_cap_init(void);
NTSTATUS vfs_cap_init(void)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap", cap_op_tuples);
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
+ &vfs_cap_fns);
}
/* For CAP functions */
}
len++;
- to = TALLOC_ARRAY(ctx, char, len);
+ to = talloc_array(ctx, char, len);
if (!to) {
return NULL;
}
size_t len = 0;
for (p1 = from; *p1; len++) {
- if (is_hex(from)) {
+ if (is_hex(p1)) {
p1 += 3;
} else {
p1++;
}
}
+ len++;
- to = TALLOC_ARRAY(ctx, char, len);
+ to = talloc_array(ctx, char, len);
if (!to) {
return NULL;
}